💡 학습 목표
- account/save.jsp 파일 생성 및 AccountController 생성 및 구현
- AccountSaveDTO 설계 하기
- 계좌 생성 기능 만들기
파싱이란?
💡 파싱(parsing)은 주어진 데이터(예: 문서, 파일, 문자열 등)를 분석하여 구조를 이해하고, 필요한 정보를 추출 또는 변환하는 과정을 의미합니다. 프로그래밍에서는 주로 원시 데이터를 원하는 형태로 가공하기 위해 사용되며, 예를 들어 HTML 문서에서 특정 데이터를 추출하거나, JSON 문자열을 객체로 변환하는 등의 작업이 파싱에 해당합니다.
클라이언트 측에서 데이터를 서버로 보내면 그 값을 분석해서 원하는 객체로 변경을 해 주는지 동작 흐름을 다시 한번더 조사해보세요
account/save.jsp 파일 생성 및 AccountController 생성 및 구현
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- header.jsp -->
<%@ include file="/WEB-INF/view/layout/header.jsp"%>
<!-- start of content.jsp(xxx.jsp) -->
<div class="col-sm-8">
<h2>계좌생성(인증)</h2>
<h5>Bank App에 오신걸 환영합니다</h5>
<!-- 예외적으로 로그인은 보안 때문에 post로 던지자 -->
<!--
insert into account_tb(number, password, balance, user_id, created_at)
-->
<form action="/account/save" method="post">
<div class="form-group">
<label for="number">number:</label>
<input type="text" class="form-control" placeholder="Enter number" id="username" name="number" value="1002-1234" >
</div>
<div class="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" placeholder="Enter password" id="pwd" name="password" value="1234">
</div>
<div class="form-group">
<label for="balance">number:</label>
<input type="number" class="form-control" placeholder="Enter balance" id="username" name="balance" value="10000" >
</div>
<div class="text-right">
<button type="submit" class="btn btn-primary">계좌 생성</button>
</div>
</form>
</div>
<!-- end of col-sm-8 -->
</div>
</div>
<!-- end of content.jsp(xxx.jsp) -->
<!-- footer.jsp -->
<%@ include file="/WEB-INF/view/layout/footer.jsp"%>
SaveDTO 생성
package com.tenco.bank.dto;
import com.tenco.bank.repository.model.Account;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class SaveDTO {
private String number;
private String password;
private Long balance;
public Account toAccount(Integer userId) {
return Account.builder()
.number(this.number)
.password(this.password)
.balance(this.balance)
.userId(userId)
.build();
}
}
AccountController.java 파일 생성 및 구현
package com.tenco.bank.controller;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tenco.bank.dto.SaveDTO;
import com.tenco.bank.handler.exception.DataDeliveryException;
import com.tenco.bank.handler.exception.UnAuthorizedException;
import com.tenco.bank.repository.model.User;
import com.tenco.bank.service.AccountService;
import jakarta.servlet.http.HttpSession;
@Controller // IoC 대상(싱글톤으로 관리)
@RequestMapping("/account")
public class AccountController {
// 계좌 생성 화면 요청 - DI 처리
private final HttpSession session;
private final AccountService accountService;
// @Autowired
public AccountController(HttpSession session, AccountService accountService) {
this.session = session;
this.accountService = accountService;
}
/**
* 계좌 생성 페이지 요청
* 주소 설계 : <http://localhost:8080/account/save>
* @return save.jsp
*/
@GetMapping("/save")
public String savePage() {
// 1. 인증 검사가 필요(account 전체가 필요함)
User principal = (User)session.getAttribute("principal");
if(principal == null) {
throw new UnAuthorizedException("인증된 사용자가 아닙니다", HttpStatus.UNAUTHORIZED);
}
return "account/save";
}
/**
* 계좌 생성 기능 요청
* 주소 설계 : <http://localhost:8080/account/save>
* @return : 추후 계좌 목록 페이지 이동 처리
*/
@PostMapping("/save")
public String saveProc(SaveDTO dto) {
// 1. form 데이터 추출 (파싱 전략)
// 2. 인증 검사
// 3. 유효성 검사
// 4. 서비스 호출
User principal = (User)session.getAttribute("principal");
if(principal == null) {
throw new UnAuthorizedException("인증된 사용자가 아닙니다.", HttpStatus.UNAUTHORIZED);
}
if(dto.getNumber() == null || dto.getNumber().isEmpty()) {
throw new DataDeliveryException("계좌 번호를 입력하세요", HttpStatus.BAD_REQUEST);
}
if(dto.getPassword() == null || dto.getPassword().isEmpty()) {
throw new DataDeliveryException("계좌 비밀번호를 입력하세요", HttpStatus.BAD_REQUEST);
}
if(dto.getBalance() == null || dto.getBalance() <= 0) {
throw new DataDeliveryException("계좌 잔액을 입력하세요", HttpStatus.BAD_REQUEST);
}
accountService.createAccount(dto, principal.getId());
return "redirect:/index";
}
}
AccountService 생성
package com.tenco.bank.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.tenco.bank.dto.SaveDTO;
import com.tenco.bank.handler.exception.DataDeliveryException;
import com.tenco.bank.handler.exception.RedirectException;
import com.tenco.bank.repository.interfaces.AccountRepository;
@Service
public class AccountService {
private final AccountRepository accountRepository;
@Autowired // 생략 가능 - DI 처리
public AccountService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
/**
* 계좌 생성 기능
* @param dto
* @param id
*/
// 트랜 잭션 처리
@Transactional
public void createAccount(SaveDTO dto, Integer principalId) {
int result = 0;
try {
result = accountRepository.insert(dto.toAccount(principalId));
} catch (DataAccessException e) {
throw new DataDeliveryException("잘못된 요청입니다", HttpStatus.INTERNAL_SERVER_ERROR);
} catch (Exception e) {
throw new RedirectException("알 수 없는 오류 입니다", HttpStatus.SERVICE_UNAVAILABLE);
}
if(result == 0) {
throw new DataDeliveryException("정상 처리 되지 않았습니다", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
결과 확인
: 동일한 번호에 계좌 생성 요청을 한번더 요청해서 예외 처리가 정상적으로 동작 하는지 확인해주세요
'Spring boot > Bank App 만들기' 카테고리의 다른 글
18. 중간 리팩토링 (0) | 2024.08.08 |
---|---|
17. 계좌 목록 만들기(1단계) (0) | 2024.08.08 |
15. 헤더 링크 설정 및 JSTL 태그 활용 (0) | 2024.08.08 |
14. 로그인 처리(세션 메모리지는 누가 관리하고 있을까?) (0) | 2024.08.08 |
13. 회원 가입(트랜잭션, 예외 처리, H2 테이블 생성) (0) | 2024.08.08 |