[Spring] spring-boot Exception 처리

99winnmin·2022년 7월 11일
0

Spring

목록 보기
4/17

Exception 처리

web application의 입장에서 바라 보았을 때, 에러가 났을 때 내려줄 수 있는 방법은 많지 않다.
1. 에러 페이지
2. 4xx Error OR 5xx Error
3. Client가 200외에 처리를 하지 못 할 때는 200을 내려주고 별도의 에러 Message 전달

  • 기본적인 2가지 처리 방법(전역으로 처리 or 특정 api에서 처리하는 방식)

아래 코드는 특정 ApiController에 대해 예외처리하는 방식의 모범사례임
코드가 깔끔하지는 않지만 예외처리가 되는 logic를 파악해야함
advice객체에서 controller에 대한 예외처리를 모두 대비하고 있는 방식

  • 예외가 발생될 ApiController
package com.example.spring.controller;

import ...

@RestController
@RequestMapping("/api")
@Validated // @Validated 로 required = false가 없어도 유효성 검사를 하게함
public class ExceptApiController {

    // required = false 는 requestParam이 없어도 되지만 null이 들어가게됨
   @GetMapping("/except/get")
    public ExceptionUser get(
            @Size(min = 2)
            @RequestParam String name,

            @NotNull
            @Min(1)
            @RequestParam Integer age){
        ExceptionUser exceptionUser = new ExceptionUser();
        exceptionUser.setName(name);
        exceptionUser.setAge(age);

        int a = 10+age;

        return exceptionUser;
    }

    @PostMapping("/except/post")
    public ExceptionUser post(@Valid @RequestBody ExceptionUser exceptionUser){
        System.out.println(exceptionUser);
        return exceptionUser;
    }

    // Controller 안에 ExceptionHandler를 코딩하게 되면 이 class 안에서 발생하는 예외에만 관여하게됨
    // GlobalHandler 보다 우선순위가 높아서 여기서 예외처리하고 끝
   /*@ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity methodArgumentNotValidException(MethodArgumentNotValidException e){
       System.out.println("api controller");
       return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }*/
}
  • 해당 객체에 대한 예외처리 advicer
package com.example.spring.advice;

import ...

// (basePackageClasses = ExceptApiController.class) 이것으로 해당 
// ApiController에 대한 처리만 하겠다고 명시하는것
// 없으면 전역처리임
@RestControllerAdvice(basePackageClasses = ExceptApiController.class)
public class ExceptApiControllerAdvice {

    @ExceptionHandler(value = Exception.class)
    public ResponseEntity exception(Exception e){
        System.out.println(e.getClass().getName());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity methodArgumentNotValidException(MethodArgumentNotValidException e,
                                                          HttpServletRequest httpServletRequest){
        // 에러 list 선언
        List<Error> errorList = new ArrayList<>();

        BindingResult bindingResult = e.getBindingResult();
        bindingResult.getAllErrors().forEach(error -> {
            FieldError field = (FieldError) error;

            String fieldName = field.getField();
            String message = field.getDefaultMessage();
            String value = field.getRejectedValue().toString();

            Error errorMessage = new Error();
            errorMessage.setField(fieldName);
            errorMessage.setMessage(message);
            errorMessage.setInvalidValue(value);

            errorList.add(errorMessage);
        });
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setErrorList(errorList);
        errorResponse.setMessage("");
        errorResponse.setRequestUrl(httpServletRequest.getRequestURI());
        errorResponse.setStatusCode(HttpStatus.BAD_REQUEST.toString());
        errorResponse.setResultCode("FAIL");

        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    // 해당 방식으로 예외처리 메세지를 client에게 이쁘게 전달할 수 있음

출처 : 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.

profile
功在不舍

0개의 댓글