annotation
1. RequiredArgsConstructor
속성에 final을 적용하고 롬복의 @RequiredArgsConstructor
애너테이션을 적용하면
해당 속성을 필요로하는 생성자가 롬복에 의해 자동으로 생성된다. (※ final이 없는 속성은 생성자에 포함되지 않는다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
// @Setter
public class HelloLombok {
private final String hello;
private final int lombok;
public static void main(String[] args) {
HelloLombok helloLombok = new HelloLombok("헬로", 5);
System.out.println(helloLombok.getHello());
System.out.println(helloLombok.getLombok());
}
}
final을 적용했기 때문에 @Setter는 의미가 없으며 Setter 메서드들도 사용할수 없다. final은 한번 설정한 값을 변경할수 없게 하는 키워드이다.
@ExceptionHandler
Spring MVC에서 에러를 처리하는 방식 2가지 :
HandlerExceptionResolver
,@ExceptionHandler
@ExceptionHandler
는 Controller레벨에서만 작동
- Controller 계층에서 발생하는 에러를 잡아서 메소드로 처리해주는 기능
- Base Controller 클래스를 상속한 Controller만 해당됨.
- Service, Repository에서 발생하는 에러는 제외함
HandlerExceptionResolver는 통일된 예외 처리 메커니즘을 구현할 수 있다.
- ExceptionHandlerExceptionResolver
- DefaultHandlerExceptionResolver
- 응답의 상태 코드를 적절하게 설정한다.
- 제한 사항: 응답 본문에 아무 것도 설정하지 않는다는 것 (애플리케이션이 실패에 대한 추가 정보를 제공할 수 있도록 응답에도 본문이 있어야 한다.)
- ResponseStatusExceptionResolver
- 사용자 정의 예외에 사용할 수 있는
@ResponseStatus
주석을 사용 하고 이러한 예외를 HTTP 상태 코드에 매핑 - 응답 본문을 처리하는 방식이 제한이 있음 (응답에 상태코드를 매핑하지만 본문은 null)
- 사용자 정의 예외에 사용할 수 있는
- 사용자 정의 HandlerExceptionResolver
- 장점 : spring RESTful 서비스에 오류 처리 메커니즘 생성
- 단점 : 응답 본문을 제어할 수 없음
@ControllerAdvice
@ExceptionHandler
에@ControllerAdvice
을 붙이면 전역으로 사용 가능@Controller
와 handler에서 발생하는 에러들을 모두 잡아준다.- 흩어져 있던 여러
@ExceptionHandler
를 단일 전역 오류 처리 구성 요소로 통합 할 수 있다 - 응답 본문과 상태 코드를 완전히 제어할 수 있다.
- 함께 처리되도록 동일한 메서드에 대한 여러 예외 매핑을 제공한다.
- 최신 RESTful ResposeEntity 응답을 효과적으로 활용한다. (ResponseEntity는 HttpEntity를 상속 받았다. HttpEnitiy는 HttpMessageConverter로 컨버팅이 된다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
@ControllerAdvice
public class RestResponseEntityExceptionHandler
extends ResponseEntityExceptionHandler {
@ExceptionHandler(value
= { IllegalArgumentException.class, IllegalStateException.class })
protected ResponseEntity<Object> handleConflict(
RuntimeException ex, WebRequest request) {
String bodyOfResponse = "This should be application specific";
return handleExceptionInternal(ex, bodyOfResponse,
new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}
주의할 것
@ExceptionHandler
로 선언된 예외를 메서드의 인수로 사용되는 예외와 일치시켜야 한다.
ResponseStatusException (Spring 5 이상)
- HttpStatus 를 제공 하고 선택적으로 이유 와 원인을 제공하는 인스턴스를 만들 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
@GetMapping(value = "/{id}")
public Foo findById(@PathVariable("id") Long id, HttpServletResponse response) {
try {
Foo resourceById = RestPreconditions.checkFound(service.findOne(id));
eventPublisher.publishEvent(new SingleResourceRetrievedEvent(this, response));
return resourceById;
}
catch (MyResourceNotFoundException exc) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Foo Not Found", exc);
}
}