@RestControllerAdvice - 1
에러는 어떻게 조금 더 편하게 처리할 수 있을까
프로젝트를 진행하면서 제일 큰 고심과 역경은 애플리케이션을 실행하였을 때 IDE 로그에 빨간 글씨와 여러 코드줄이 줄줄히 등장하면 두통이 엄청 올 것이다.
그리고 이러한 문제들을 처리하기 위해서는 로그들을 읽어보고 여러 코드를 지우고 바꿔보거나 검색을 하는 등 최악의 상황이면 해결이 하지 못해 상심이 크기도 하다.
이러한 문제점을 조금이나마 해결할 수 있게 방법을 찾을 수 있게끔 개발자들은 다양한 예외처리를 설정해둔다.
그래서 이번에는 @RestControllerAdvice에 대해서 학습을 해보자
@RestControllerAdvice
Json 형태로 객체 데이터를 반환할 수 있으며, Spring MVC의 컨트롤러 @Controller와 Restuful 웹서비스의 컨트롤러의 @RestController그리고 이 컨트롤러에 발생할 수 있는 예외를 처리하는 어노테이션이 @RestControllerAdvice 이다.
그렇다면 클래스를 만들어서 RestControllerAdvice선언하면 끝인가?
@ExceptionHandler
이 어노테이션은 RestControllerAdvice를 정의한 메서드에 선언하여 자신이 지정한 해당 예외가 발생하였을 때, 본인이 지정한 로직으로 처리할 수 있다.
Swagger UI에 파라미터에 없는 값을 전송하였을 때, 출력되는 에러 코드이다.
어디서에서 어떤 에러가 발생하였는지 한눈에 보기 불편하고 가독성도 좋지 않다. 그렇다면 이러한 에러를 처리하기 편하게 @RestControllerAdvice를 설계해보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RestControllerAdvice
@Log4j2
public class CustomRestAdvice {
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
public ResponseEntity<Map<String,String>>addBindHandler(BindException e){
Map<String, String> errorMap = new HashMap<>();
if(e.hasErrors()){
BindingResult bindingResult = e.getBindingResult();
bindingResult.getFieldErrors().forEach(fieldError -> {
errorMap.put(fieldError.getField(), fieldError.getCode());
});
}
return ResponseEntity.badRequest().body(errorMap);
}
실제로 동작 여부를 확인하기 위해서 Controller의 코드들을 수정해보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Operation(summary = "Reply 등록", description = "POST 방식으로 등록")
@PostMapping(value = "/", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, Long>> register(@Valid @RequestBody ReplyDTO replyDTO,
BindingResult bindingResult)throws BindException{
Map<String, Long> resultMap = new HashMap<>();
if(bindingResult.hasErrors()){
throw new BindException(bindingResult);
}
resultMap.put("rno",111L);
return ResponseEntity.ok(resultMap);
}
@RestControllerAdvice 제대로 설계하였다면 컨트롤러에서 발생하는 예외에 대해 JSON과 같은 응답 메세지를 생성해서 보낼 수 있다.
handleBindException()은 컨트롤러에서 BindException이 던져지는 경우 이를 이용해 JSON 메시지와 400에러를 전송하게 된다.
다시 빈 혹은 잘못된 값을 전송하게 되면 내가 지정한 에러 메세지를 전송 받을 수 있다.
이런식으로 @ExceptionHandler뿐만 아니라 여러 예외 처리를 할 수 있는 기술들이 많으니 활용하면 유지보수하기 편리하지 않을까 생각하면서 더욱 전진해보자