티스토리 뷰

 업무에서 파라미터 유효성 체크를 할 때 각 클래스마다 checkParam의 방식으로 유효성 체크를 해왔는데, 좀 더 편하게 할 수 있는 방법이 없을까 고민했고, 이 글은 고민했던 내용을 적은 것이다.


 우선은 기존에도 가지고 있었지만 사용하지는 않았던 Validation을 사용해보기로 했다.

기본적인 흐름은 다음과 같다.

1. 컨트롤러의 메서드 호출

2. @Valid 어노테이션이 붙은 파라미터의 유효성 조건 체크

3. 유효성 조건을 만족하지 못하면 ControllerAdvisor의 해당 Exception의 ExceptionHandler 어노테이션이 붙은 메서드가 수행된다.


@Controller
@RequestMapping("/post")
public class TestPostController {    
    
    @ResponseBody
    @PostMapping("/completeAjax")
    public SingleResult completeAjax(@RequestBody @Valid Post post) {
        // 예시라 비즈니스 로직 제외
        SingleResult singleResult = new SingleResult(ResponseCode.OK);
        return singleResult;
    }
    
}

위와 같이 컨트롤러의 메서드가 있다고 하면 /post/completeAjax를 호출했을 때 Post의 유효성 검사를 하게 된다. 유효성 검사를 하게 될 때 사용하는 조건은 Post 클래스에 아래와 같이 정의한다.

@Getter
@Setter
@AllArgsConstructor
@ToString
public class Post {

    @Size(min = 1, max = 10, message = "제목은 10자까지 가능합니다.")
    private String title;

    @Size(min = 1, message = "내용은 입력되어야 합니다.")
    private String content;

}

위처럼 각 필드마다 조건을 정의하고, Exception이 발생했을 때의 메시지를 지정해줄 수 있다. 이 조건을 만족하지 못하면 BindException(혹은 MethodArgumentNotValidException)이 발생하게 되고, 그러면 이 Exception을 handle해주는 메서드를 호출하게 된다.

@ControllerAdvice
@RestController
public class ExceptionAdvisor {

    @ExceptionHandler(BindException.class)
    public BaseResult processValidationError(BindException exception) {
        BindingResult bindingResult = exception.getBindingResult();

        StringBuilder builder = new StringBuilder();

        BaseResult baseResult = new BaseResult(ResponseCode.WRONG_PARAMETER_VALUE_ERROR);

        if (bindingResult.hasFieldErrors()) {
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                 builder.append(fieldError.getDefaultMessage());
            }
        }

        baseResult.setResultMessage(builder.toString());

        return baseResult;
    }

}

 위와 같이 처리했을 때 기존과는 다른 점이 몇 가지 생겼다.

1. 더 이상 컨트롤러 내부에서 파라미터 체크를 하지 않아도 된다. -> 코드가 자신이 할 일에만 집중되어 간결해진다.

2. 파라미터를 체크할 클래스에서 체크조건을 명시하기 때문에 유효성정책을 훨씬 더 알아보기 쉽다.

 반면 아쉬운 점도 있었다. @ControllerAdvice는 적용범위를 아래의 조건에 따라 제한할 수 있다.

1. 특정 어노테이션을 가지고 있는지

2. 특정 패키지 이하에 존재하는지

3. 특정 클래스 타입인지

이때, 내가 원하는 조건에 따라 제한할 수가 없어서 그 부분이 아쉬웠다. 파라미터 체크를 한 후, 뷰를 돌려줘야할 수도 있고 객체를 돌려줘야할 수도 있는데 이 부분이 우리 업무구조상 같은 클래스에 존재하기 때문에 어떻게 뜯어내야할지 애매했다. 가장 간단한 방법은 그냥 ajax를 사용하거나 api처럼 객체를 돌려줘야할 때만 들어오는 파라미터에 @Valid를 사용하게 하는 것인데... 더 좋은 방법이 있을지 생각해봐야겠다.

300x250

'공부흔적 > 스프링' 카테고리의 다른 글

Transaction 관련 내부 코드 뜯어보기  (0) 2022.08.02
중첩된 @Transactional을 실험해보자  (0) 2022.07.27
DispatcherServlet 뜯어보기  (0) 2022.03.20
체크박스 객체로 받기  (0) 2021.09.28
Spring mvc interceptor  (0) 2021.05.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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
글 보관함