Web Application의 입장에서 에러가 났을 때 에러를 내려줄 수 있는 방법은 아래와 같다
1. 에러 페이지
2. 4xx Error or 5xx Error
3. Client 가 200 외에 처리를 하지 못 할 때는 200을 내려주고 별도의 에러 Message를 전달
두 가지 요청이 있다
Get 요청 컨트롤러의 경우 이름과 age를 파라미터로 받는고 age 는 Integer 타입이기 때문에 값이 없다면 null로 들어오게 된다 . setAge 부분에서 NullPointerExcetion(NPE라고 하겠다)이 발생할 것이다 .
요청과 응답 결과는 아래 그림과 같다
서버쪽에서 NPE 가 발생했기 때문에 500 에러가 발생했다 기본적인 정보는 들어가 있지만 어떤에러가 발생했는지는 알 수 없다.
Post 요청에서는 annotation을 통해 검증하고 user를 검증하고 있다.
User 클래스에선 위와 같이
name 에 대해서는 빈 값이면 안되고 사이즈는 최소 1 최대 10이도록
age에 대해서는 최소값이 1이도록 검증하게 했다 .
요청 결과는 아래 그림과 같다 .
클라이언트에서 잘못된 값을 넘겨주었기 떄문에 400 에러가 발생한다 위의 Get 요청과 같이 기본적인 정보만 들어가게 된다 클라이언트가 알 수 있는 정보가 많지 않다 .
예외 처리를 통해 조금 더 친절하게 해보자
@RestControllerAdvice //RestAPI 컨트롤러용 advice
//@ViewResolverAdvice MVC 형식일때의 advice
public class GlobalControllerAdvice {
@ExceptionHandler(value = Exception.class)
public ResponseEntity exception(Exception e){
System.out.println(e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
}
}
2가지 방법이 있다
1.@ControllerAdvice을 붙힌 advice 클래스를 만들어서 @ExceptionHandler를 지정하면 애플리케이션 전역(Global)에서 일어나는 예외를 잡을때 사용된다.
2.특정 컨트롤러에 @ExceptionHandler를 붙힌 메서드를 만든다.
@ControllerAdvice가 지정되어 있더라도 우선순위는 컨트롤러내의 @ExceptionHandler이 위에 있기때문에 해당 클래스안에서만 @ExceptionHandler가 적용된다
1번 방법을 먼저 알아보자
Advice 클래스를 만들어야한다 .
@RestControllerAdvice는 Rest 형식의 컨트롤러에서 사용되는 advice이다 애플리케이션 전역(Global)에서 일어나는 예
외를 잡을때 사용된다.
@ExceptionHandler는 예외를 핸들링하는 annotation이다
핸들링할 메서드를 만들고 @ExceptionHandler을 붙힌 후에 해당 메서드에 핸들링 로직을 구현한다.
RestAPI 이기 때문에 ResponseEntity를 리턴한다.
위의 경우 value로 Exception 타입을 받기 떄문에 모든 예외상황이 잡힌다.
파라미터로 @ExceptionHandler에 지정한 예외를 받아서 사용할 수도 있다 .
@RestControllerAdvice //RestAPI 컨트롤러용 advice
//@ViewResolverAdvice MVC 형식일때의 advice
public class GlobalControllerAdvice {
//모든 Exception 에 대해서 잡아낸다.
@ExceptionHandler(value = Exception.class)
public ResponseEntity exception(Exception e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
}
//특정 Exception 을 지정해서 잡아낸다.
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public ResponseEntity MethodArgumentNotValidException(MethodArgumentNotValidException e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
ControllerAdvice를 지정해서 예외를 잡아내고 ResponseEntity를 생성해서 리턴해주었다 응답코드는 400번이며
응답바디에는 해당 예외에 대한 메시지가 담겨있다 .
요청을 보내보면 아래 그림과 같다.
메시지가 잘 정리되어 있지는 않지만 더 많은 정보가 담겨있다 .
@RestControllerAdvice의 옵션으로 basePackages 를 지정해주면 예외를 잡아낼 범위를 지정해 줄 수도 있다 .
예시)
@RestControllerAdvice(basePackages = "com.example.hello.exception.*")
2번 방법으로 특정 컨트롤러에 @ExceptionHandler를 지정해 보잡
@RestController
@RequestMapping("/api/user")
public class ExceptionController {
@PostMapping("")
public User post(@Valid @RequestBody User user){
System.out.println(user);
return user;
}
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public ResponseEntity MethodArgumentNotValidException(MethodArgumentNotValidException e){
System.out.println("controller handler");
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("controller handler");
}
}
컨트롤러에 @ExceptionHandler를 만들었다 현재 위의 @ControllerAdvice로 glabal 로도 똑같은 핸들러가 지정되
있는 상태이다 우선순위는 Controller 안에 Handler가 위이기 때문에 응답 바디에 controller handler가 찍힐 것이다.
'SPRING BOOT' 카테고리의 다른 글
Spring boot 공부 5 - filter (0) | 2021.05.21 |
---|---|
Spring boot 공부 4 - Error 데이터 커스터마이징해서 응답 (0) | 2021.05.20 |
Spring boot 공부 2 - validation 과 custom validation 만들기 (0) | 2021.05.20 |
Spring boot 공부 1 - ObjectMapper (0) | 2021.05.19 |
Spring boot Lombok 사용을 위한 셋팅 (0) | 2020.11.19 |