1. 계좌 생성 과정 개요
웹 애플리케이션에서 계좌 생성 기능을 구현하려면 다음과 같은 흐름이 필요합니다.
기본 흐름
1️⃣ 사용자가 계좌 생성 페이지로 이동
2️⃣ 계좌 정보를 입력하고 제출
3️⃣ 서버에서 인증 검사 (로그인 확인)
4️⃣ 입력 값 검증 (유효성 검사)
5️⃣ DB에 계좌 정보 저장
6️⃣ 성공 시 다음 페이지로 리다이렉트
2. 계좌 생성 화면 만들기
JSP 파일 (account/save.jsp)
사용자가 계좌 정보를 입력할 수 있는 페이지입니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 공통 헤더 포함 -->
<%@ include file="/WEB-INF/view/layout/header.jsp"%>
<div class="col-sm-8">
<h2>계좌 생성 🏦</h2>
<h5>Bank App에 오신 걸 환영합니다.</h5>
<form action="/account/save" method="post">
<div class="form-group">
<label for="number">계좌 번호:</label>
<input type="text" name="number" class="form-control" placeholder="계좌 번호 입력" id="number" required>
</div>
<div class="form-group">
<label for="pwd">계좌 비밀번호:</label>
<input type="password" name="password" class="form-control" placeholder="비밀번호 입력" id="pwd" required>
</div>
<div class="form-group">
<label for="balance">입금 금액:</label>
<input type="number" name="balance" class="form-control" placeholder="입금 금액 입력" id="balance" required>
</div>
<div class="text-right">
<button type="submit" class="btn btn-primary">계좌 생성</button>
</div>
</form>
</div>
<!-- 공통 푸터 포함 -->
<%@ include file="/WEB-INF/view/layout/footer.jsp"%>
- 사용자가 계좌 번호, 비밀번호, 입금 금액을 입력하고 제출합니다.
- POST /account/save 요청을 보내 계좌 생성 요청을 처리합니다.
- 필수 입력 필드를 required 속성으로 지정하여 기본적인 프런트엔드 유효성 검사 수행.
3. 계좌 생성 요청 처리 (Controller)
AccountController - 계좌 요청 관리
package com.tenco.bank.controller;
import org.springframework.beans.factory.annotation.Autowired;
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.AccountSaveDTO;
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
@RequestMapping("/account")
public class AccountController {
private final HttpSession session;
private final AccountService accountService;
@Autowired
public AccountController(HttpSession session, AccountService accountService) {
this.session = session;
this.accountService = accountService;
}
// 계좌 생성 페이지 요청 (GET)
@GetMapping("/save")
public String savePage() {
User principal = (User) session.getAttribute("principal");
if (principal == null) {
throw new UnAuthorizedException("로그인이 필요합니다.", HttpStatus.UNAUTHORIZED);
}
return "account/save";
}
// 계좌 생성 요청 처리 (POST)
@PostMapping("/save")
public String saveProc(AccountSaveDTO dto) {
// 1️⃣ 인증 검사 (로그인 여부 확인)
User principal = (User) session.getAttribute("principal");
if (principal == null) {
throw new UnAuthorizedException("로그인 먼저 해주세요.", HttpStatus.UNAUTHORIZED);
}
// 2️⃣ 유효성 검사
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);
}
// 3️⃣ 계좌 생성 서비스 호출
accountService.createAccount(dto, principal.getId());
// TODO: 계좌 목록 페이지가 완성되면 `/account/list`로 변경 예정
return "redirect:/account/save";
}
}
- GET /account/save → 로그인한 사용자만 접근 가능.
- POST /account/save →
1️⃣ 로그인 여부 확인 (인증 검사)
2️⃣ 계좌 번호, 비밀번호, 입금 금액 입력 여부 검사 (유효성 검사)
3️⃣ 계좌 생성 요청 (AccountService 호출)
4. 계좌 정보 DTO (Data Transfer Object)
AccountSaveDTO - 계좌 데이터 관리
package com.tenco.bank.dto;
import com.tenco.bank.repository.model.Account;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AccountSaveDTO {
private String number;
private String password;
private Long balance;
// DTO -> Account 객체 변환 (DB 저장용)
public Account toAccount(int principalId) {
return Account.builder()
.number(this.number)
.password(this.password)
.balance(this.balance)
.userId(principalId)
.build();
}
}
- AccountSaveDTO는 계좌 정보를 Account 엔터티로 변환하는 역할을 합니다.
- 사용자의 id를 받아서 Account 객체 생성.
5. 계좌 생성 서비스 (Service)
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.AccountSaveDTO;
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
public AccountService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
@Transactional
public void createAccount(AccountSaveDTO dto, Integer principalId) {
try {
accountRepository.insert(dto.toAccount(principalId));
} catch (DataAccessException e) {
throw new DataDeliveryException("잘못된 처리입니다.", HttpStatus.INTERNAL_SERVER_ERROR);
} catch (Exception e) {
throw new RedirectException("알 수 없는 오류가 발생했습니다.", HttpStatus.SERVICE_UNAVAILABLE);
}
}
}
- createAccount() 메서드는 AccountRepository를 통해 계좌를 DB에 저장.
- 예외 발생 시 적절한 응답 반환.
- @Transactional을 사용하여 데이터의 일관성을 보장.
6. 계좌 데이터베이스 저장 (MyBatis)
<insert id="insert">
insert into account_tb (number, password, balance, user_id, created_at)
values (#{number}, #{password}, #{balance}, #{userId}, now())
</insert>
- 새로운 계좌를 account_tb 테이블에 저장하는 SQL 문.
- created_at은 현재 시간으로 자동 설정.
계좌 생성 페이지 (save.jsp)
컨트롤러에서 인증 및 유효성 검사 처리
DTO를 통해 데이터 변환
서비스 계층에서 계좌 등록 처리
MyBatis를 활용한 DB 저장