[Spring] @ControllerAdvice 를 이용한 예외 처리

    @ControllerAdvice 를 이용한 예외 처리

    이슈

    • 회사에서는 내려줘야 할 Response 에러 포맷이 정해져 있다.
    • 에러를 아름답게 형식화하여 json으로 내려주고 싶다

    해결

    • @ControllerAdvice 로 커스터마이징하여 특정 컨트롤러, 예외 타입에 대해 반환할 응답 JSON 을 정의 할 수 있다.
    • 주요 예외 처리는 다음과 같다.
    @ControllerAdvice
    public class CustomRestExceptionHandler {
    
        @ExceptionHandler(HttpMessageNotReadableException.class)
        public ResponseEntity<Map<String, String>> handleHttpMessageNotReadableException(
                HttpMessageNotReadableException ex) {
            // 아예 잘못된 형식으로 request 를 요청할 경우 예외 발생
            Map<String, String> error = new HashMap<>();
            error.put("code", "ERR5001");
            error.put("message", "Required request body is missing");
    
            return ResponseEntity.badRequest().body(error);
        }
    
        @ExceptionHandler(MissingServletRequestParameterException.class)
        public ResponseEntity<Map<String, String>> handleMissingServletRequestParameterException(
                MissingServletRequestParameterException ex) {
            Map<String, String> error = new HashMap<>();
            error.put("code", "ERR5002");
            error.put("message", ex.getParameterName() + " is missing");
            return ResponseEntity.badRequest().body(error);
        }
    
        @ExceptionHandler(MethodArgumentNotValidException.class)
        public ResponseEntity<Map<String, String>> handleMethodArgumentNotValidException(
                MethodArgumentNotValidException ex) {
    
            List<String> params = new ArrayList<>();
            for (FieldError error : ex.getBindingResult().getFieldErrors()) {
                params.add(error.getField());
            }
            String errorStr = String.join(",", params);
    
            Map<String, String> error = new HashMap<>();
            error.put("code", "ERR5003");
            error.put("message", errorStr + " is invalid");
            return ResponseEntity.badRequest().body(error);
        }
    
        @ExceptionHandler(Exception.class)
        public final ResponseEntity<Object> handleAllExceptions(Exception ex) {
            Map<String, String> error = new HashMap<>();
            error.put("code", "ERR5000");
            error.put("message", ex.getMessage());
            return ResponseEntity.badRequest().body(error);
        }
    }

    요청-응답 결과

    1. post 요청 시 requstbody용 json 을 아예 보내지 않는 등의 읽을 수 없는 포맷으로 요청 할 때
    • 응답
    {
        "code": "ERR5001",
        "message": "Required request body is missing"
    }
    1. 파라미터가 누락 되었을 때
    • 요청 : boardType 이 필수 파라미터인데 생략하고 요청하였을 때
        @GetMapping("/board")
        public PageResultDTO<BoardDTO, Object[]> list(
                @RequestParam(value = "boardType", required=true) String boardType) {
            PageResultDTO<BoardDTO, Object[]> result = service.getList(pageRequestDTO, boardType);
            return result;
        }
    • 응답
    {
        "code": "ERR5002",
        "message": "boardType is missing"
    }
    1. 파라미터의 조건이 invalid 할 때
    • 요청 : Controller 에 @Valid 있고 BoardDTO 에 유효성 검사 규칙을 명시해 두어야 함
        @PostMapping("/board")
        public BoardDTO register(@RequestBody @Valid BoardDTO boardDTO) {
            return service.register(boardDTO);
        }
    • 응답
    {
        "code": "ERR5003",
        "message": "writerId is invalid"
    }

    참고

    반응형

    댓글

    Designed by JB FACTORY