티스토리 뷰

728x90

예외 처리는 한 가지 포맷을 통해서 처리하는 것이 가장 좋다.

그리고 그 포맷은 ExceptionHandler와 ControllerAdvice를 이용해서 미리 정해진 ErrorMessage 포맷을 이용한 JSON 데이터로 처리하는 것이 가장 보편적이다.

 

하지만 혼자서 프로젝트를 진행하여 뷰나 리액트에 깊이가 있지 않으면 렌더링을 위해서 타임리프같은 템플릿 엔진을 사용할 수 밖에 없었기때문에 

전체 프로젝트에서 군데군데 타임리프로 예외처리를 하는 일이 발생했다.

 

단순한 Validation 체크라면 Controller에서 BindingResult를 통해 바로 되돌려 보내면 되지만

Service layer에서 발생하는 비즈니스 로직에 의한 예외 처리가 항상 헷갈렸다.

 

정확히는 타임리프는 던져지는 예외에 대해서 처리를 할 수 없다. 

예외 페이지를 만들어 거기로 데이터와 함께 보내는 방법이 있지만 그것은 비즈니스 로직을 처리하는 방법에 어긋나는 방법이라 생각했다.

 

예외를 BindingResult에 어떤 식으로든 담아서 되돌려보내야 한다.

 

방법은 이와 같다. 

Request 바로 뒤에 BindingResult를 선언하면 Request에 존재하는 각각의 필드에 대해 거절 권한이 생긴다.

 

Request의 여러 필드를 검증해야 한다면 Cotroller가 지저분해지기에 Validator를 구현하여 사용하는 편이 좋지만 

여기서는 Service Layer에서의 비즈니스 로직을 처리하고싶은게 주요 목표이다.

 

@PostMapping("delete")
public String deleteMeAction(DeleteMeRequest deleteMeRequest, BindingResult result, @CurrentUser User user, Model model) {
    if (!meService.passwordCheck(deleteMeRequest.getPassword(), user)) {
        result.rejectValue("password", "PASSWORD_MISMATCH", "비밀번호가 일치하지 않습니다.");
        model.addAttribute("user", user);
        return "me/delete";
    }
    meService.deleteMe(deleteMeRequest, user);

 

API에서 throw new Exception해서 던졌다면 thymeleaf를 이용하는 방법은 익셉션을 던지는 대신 flag를 이용하여 

throw해야 하는 경우마다 return false를 하는 것이다.

 

public Boolean passwordCheck(String password, User user) {

    return passwordEncoder.matches(password, user.getPassword());
}

 

여기서 return이 true가 되면 rejectValue를 아무것도 하지 않게 되니

비즈니스 로직의 검사가 통과한 것이다.

 

마지막으로 중요한 점은 Cotroller에서 reject할때 페이지 렌더링에 필요한 값을 다시 담아서 보내줘야 한다는 것이다.

즉 해당 페이지를 GET 요청할 때 Request를 제외하고 필요했던 모든 값을 다시 model에 담아서 보내야 한다.

 

그래서 return으로 되돌려 보내는 곳이 URL이 아닌 templates임을 명심해야 한다.

 

if (!meService.passwordCheck(deleteMeRequest.getPassword(), user)) {
    result.rejectValue("password", "PASSWORD_MISMATCH", "비밀번호가 일치하지 않습니다.");
    model.addAttribute("user", user);
    return "me/delete";
}

 

프로젝트 초기에 만들어둔 구조라 어거지로 타임리프로 처리하긴 했지만

단순한 데이터만 주고받는 경우에는 그냥 JSON을 이용하는 것이 BEST PRACTICE가 맞는 것같다.

 

오늘의 교훈 : API 쓰자

'Spring > 타임리프' 카테고리의 다른 글

부트스트랩 Modal로 데이터 넘기는 방법  (0) 2022.06.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함