-
bank app 18 - (intercepter 활용)spring boot 2023. 4. 21. 10:25
학습 목표
1. AuthIntercepter 구현 클래스 만들기
2. WebMvcConfig 구현 클래스 만들기
3. 코드 수정 - 인증 처리 일괄 적용 하기Spring boot 에서 인터셉터를 적용하는 방법
implements HandlerInterceptor 를 구현 받는 클래스 만들기
implements WebMvcConfigurer 를 구현 받는 클래스 만들기
HandlerInterceptor 는 spring boot MVC 에서 제공하는 인터셉터로 AOP 개념과는 다르게
서블릿 필터처럼 동작 합니다. 즉, 클라이언트의 요청이 컨트롤러에 도달하기 전에 인터셉터 요청/응답을 가로채어
필요한 로직을 수행항 수 있습니다.
반면, AOP(Aspect-Orented Programming)은 관점 지향 프로그래밍으로 횡단 관심사를 핵심 관심사(core concerns) 분리하여 구현하는 기법입니다.
따라서 HandlerInterceptor는 AOP 와는 개념적으로 다르지만 AOP와 유사한 효과를 얻을 수 있는 기능 입니다.Ecveption Handler 는 AOP와 직접적인 연관은 없습니다. 하지만 spring boot 에서 Exception Handler는
AOP와 함께 사용되는 개념 중 하나 입니다. 이를 통해서 코드의 가독성과 유지 보수성을 향상 시킬 수 있습니다.Spring Boot 에서 Validation 은 AOP 기반으로 동작하는 개념이 맞습니다.
AOP 는 메서드 호출 전, 혹은 후에 필터링 및 검증 수정 등의 작업을 가능하게 합니다.세션값이 있는지 유효성 검사를 하는 인터셉터를 만들어준다.
package com.tenco.bank.handler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import com.tenco.bank.handler.exception.CustomRestfullException; import com.tenco.bank.handler.exception.UnAuthorizedException; import com.tenco.bank.repository.model.User; import com.tenco.bank.utils.Define; // 1. HandlerInterceptor 구현 // 2 @Component // Ioc 대상 - 싱글톤 관리 public class AuthInterceptor implements HandlerInterceptor { // 컨트롤러 들어가기 전 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); User principal = (User)session.getAttribute(Define.PRINCIPAL); if (principal == null) { // 1 단계 //response.sendRedirect("/user/sign-in"); // 2 단계 throw new UnAuthorizedException("로그인 먼저 해주세요", HttpStatus.UNAUTHORIZED); //return false; } return true; } // 요철 처리가 완료된 후, 즉 뷰 렌더링이 완료된 후에 호출되는 메서드 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } }com.tenco.bank안에 config 패키지를 만들어 account or auth 폴더 안에 있는 페이지를 접근할려면
세션이 있는지 유효성검사를 하게 해준다.
package com.tenco.bank.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.tenco.bank.handler.AuthInterceptor; @Configuration // Ioc 등록 - 2개 이상 빈으로 등록 될때 사용 public class WebMvcConfig implements WebMvcConfigurer { @Autowired // DI private AuthInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns("/account/**") .addPathPatterns("/auth/**"); // 1.path 더 추가 하는 방법 // account안에 실행되는것은 인증처리 해줘라 } }세션값이 null 일때 유효성 검사하는 방어적코드를 다 없애준다.
package com.tenco.bank.controller; import java.util.List; import javax.servlet.http.HttpSession; import javax.websocket.server.PathParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.tenco.bank.dto.DepositFormDto; import com.tenco.bank.dto.SaveFormDto; import com.tenco.bank.dto.TransferFormDto; import com.tenco.bank.dto.WithdrawFormDto; import com.tenco.bank.dto.response.HistoryDto; import com.tenco.bank.handler.exception.CustomPageException; import com.tenco.bank.handler.exception.CustomRestfullException; import com.tenco.bank.handler.exception.UnAuthorizedException; import com.tenco.bank.repository.model.Account; import com.tenco.bank.repository.model.User; import com.tenco.bank.service.AccountService; import com.tenco.bank.utils.Define; @Controller @RequestMapping("/account") public class AccountController { @Autowired private HttpSession session; @Autowired private AccountService accountService; //todo // 계좌목록 페이지 // 입금 페이지 // 출금 페이지 // 이체 페이지 // 계좌 상세보기 // 계좌 생성 페이지 // http:localhost:8080/account/list // http:localhost:8080/account/ /** * 계좌 목록 페이지 * @return 목록 페이지 이동 */ @GetMapping({"list", "/"}) public String list(Model model) { // todo 예외 테스트 - 삭제 예정 //throw new CustomRestfullException("인증되지 않은 사용자 입니다.", HttpStatus.UNAUTHORIZED); //throw new CustomPageException("페이지를 찾을 수 없습니다.", HttpStatus.NOT_FOUND); // prefix // subfix User principal = (User)session.getAttribute(Define.PRINCIPAL); List<Account> accountList = accountService.readAccountList(principal.getId()); // accountList에 데이터가 없을때도 있으니 방어적 코드 if (accountList.isEmpty()) { model.addAttribute("accountList", null); }else { model.addAttribute("accountList", accountList); } // View 화면으로 데이터를 내려 주는 기술 // Model,ModelAndView // ModelAndView은 동적인 것을 화면에 띄울때 사용한다. return "/account/list"; } // 출금 페이지 @GetMapping("/withdraw") public String withdraw() { return "/account/withdrawForm"; } // 출금 처리기능 @PostMapping("/withdraw-proc") public String withdrawproc(WithdrawFormDto withdrawFormDto){ User principal = (User)session.getAttribute(Define.PRINCIPAL); if (withdrawFormDto.getAmount() == null) { throw new CustomRestfullException("금액을 입력 하세요.", HttpStatus.BAD_REQUEST); } if (withdrawFormDto.getAmount().longValue() <= 0) { throw new CustomRestfullException("출금액이 0원 이하일 수는 없습니다.", HttpStatus.BAD_REQUEST); } if (withdrawFormDto.getWAccountNumber() == null || withdrawFormDto.getWAccountNumber().isEmpty()) { throw new CustomRestfullException("계좌 번호를 입력 해주세요.", HttpStatus.BAD_REQUEST); } if (withdrawFormDto.getWAccountPassword() == null || withdrawFormDto.getWAccountPassword().isEmpty()) { throw new CustomRestfullException("계좌 비밀 번호를 입력 해주세요.", HttpStatus.BAD_REQUEST); } accountService.updateAccountWithdraw(withdrawFormDto,principal.getId()); return "redirect:/account/list"; } /** * 입금처리 기능 * @return */ // 입금 페이지 @GetMapping("/deposit") public String deposit() { return "/account/depositForm"; } @PostMapping("/deposit-proc") public String depositProc(DepositFormDto depositFormDto) { User user = (User)session.getAttribute(Define.PRINCIPAL); if (depositFormDto.getAmount() == null) { throw new CustomRestfullException("금액을 입력해주세요", HttpStatus.BAD_REQUEST); } if (depositFormDto.getAmount().longValue() <= 0) { throw new CustomRestfullException("입금 금액이 0원 이하일 수 없습니다.", HttpStatus.BAD_REQUEST); } if (depositFormDto.getDAccountNumber() == null) { throw new CustomRestfullException("계좌 번호를 입력하세요", HttpStatus.BAD_REQUEST); } accountService.updateAccountDeposit(depositFormDto); //todo //서비스 호출 return "redirect:/account/list"; } // 이체 페이지 @GetMapping("/transfer") public String transfer() { return "/account/transferForm"; } // 이체기능 만들기 @PostMapping("/transfer-proc") public String transferProc(TransferFormDto transferFormDto) { User principal = (User)session.getAttribute(Define.PRINCIPAL); // 1.출금 계좌 번호 입력 여부 if (transferFormDto.getWAccountNumber() == null || transferFormDto.getWAccountNumber().isEmpty()) { throw new CustomRestfullException("출금 계좌 번호를 입력하세요", HttpStatus.BAD_REQUEST); } // 2. 입금 계좌 번호 입력 여부 if (transferFormDto.getDAccountNumber() == null || transferFormDto.getDAccountNumber().isEmpty()) { throw new CustomRestfullException("입금 계좌 번호를 입력하세요", HttpStatus.BAD_REQUEST); } // 3. 출금 계좌 비밀번호 입력 여부 if (transferFormDto.getWAccountPassword() == null || transferFormDto.getWAccountPassword().isEmpty()) { throw new CustomRestfullException("출금 계좌 비밀 번호를 입력하세요", HttpStatus.BAD_REQUEST); } // 4. 이체 금액 0원 이상 확인 if (transferFormDto.getAmount() <= 0) { throw new CustomRestfullException("이체 금액이 0원 이하일 수 없습니다. ", HttpStatus.BAD_REQUEST); } // 5. 출금 계좌 입금 계좌 번호 동일 여부 확인 if (transferFormDto.getWAccountNumber().equals(transferFormDto.getDAccountNumber())) { throw new CustomRestfullException("출금계좌와 입금계좌는 동일할 수 없습니다.", HttpStatus.BAD_REQUEST); } // 서비스 호출 accountService.updateAccountTransfer(transferFormDto, principal.getId()); return "redirect:/account/list"; } // 계좌 생성 페이지 @GetMapping("/save") public String save() { // 인증 검사 처리 return "/account/saveForm"; } /** * 계좌 생성 * 인증검사 * 유효성 검사 처리 - 0원 입력 가능, 마이너스 입력 불가 * @param saveFormDto * @return 계좌 목록 페이지 */ @PostMapping("/save-proc") public String saveProc(SaveFormDto saveFormDto) { User user = (User)session.getAttribute(Define.PRINCIPAL); if (user == null) { throw new UnAuthorizedException("로그인 먼저 해주세요.",HttpStatus.UNAUTHORIZED); } // 유효성 검사 하기 if (saveFormDto.getNumber() == null || saveFormDto.getNumber().isEmpty()) { throw new CustomRestfullException("계좌번호를 입력해주세요", HttpStatus.BAD_REQUEST); } if (saveFormDto.getPassword() == null || saveFormDto.getPassword().isEmpty()) { throw new CustomRestfullException("비밀번호를 입력해주세요", HttpStatus.BAD_REQUEST); } if (saveFormDto.getBalance() == null || saveFormDto.getBalance() < 0) { throw new CustomRestfullException("잘못된 금액 입니다", HttpStatus.BAD_REQUEST); } // 서비스 호출 accountService.createAccount(saveFormDto, user.getId()); return "redirect:/account/list"; } // 계좌 상세 보기 페이지 @GetMapping("/detail/{id}") public String detail(@PathVariable Integer id,@RequestParam(name = "type", defaultValue = "all", required = false) String type, Model model) { User principal = (User)session.getAttribute(Define.PRINCIPAL); Account account = accountService.readAccount(id); List<HistoryDto> historyList = accountService.readHistoryListByAccount(type, id); System.out.println(historyList); // 화면을 구성하기 위해 필요한 데이터 // 소유자 이름 // 계좌번호(1개), 계좌 잔액 // 거래 내역 model.addAttribute("principal",principal); model.addAttribute("account",account); model.addAttribute("historyList",historyList); return "/account/detail"; } }'spring boot' 카테고리의 다른 글
spring boot JPA (0) 2023.05.09 bank app 19 - (마이그레이션) (0) 2023.04.21 bank app 17 - 계좌 상세보기(2) (0) 2023.04.20 bank app 16 - 계좌 상세보기(1) (0) 2023.04.20 bank app 10 (0) 2023.04.18