@ControllerAdvice
@ControllerAdvice
Spring 에서 공통 및 전역적으로 예외처리, ModelAttribute 등 핸들링 하기 위해
@ControllerAdvice 어노테이션을 사용할 수 있다.
모든 @Controller 또는 @RestController 에 적용되는 컴포넌트이다.
- 예외 처리(@ExceptionHandler)
- 바인딩 설정(@InitBinder)
- 모델 속성 추가(@ModelAttribute)
예외처리(@ExceptionHandler)
예외처리를 위한 try-catch 문을 사용하는게 아닌 전역적으로 예외처리를 하고 싶을때 사용한다.
package com.obo.controller.global;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionController {
@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> nullHandler(NullPointerException ex) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("NULL 오류 발생");
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> exceptionHandler(Exception ex){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Exception 서버 에러");
}
}
@GetMapping(value = "/main")
public String testMain() {
System.out.println("testCount : "+testService.testCount());
String a = null;
a.substring(1);
return "test";
}
String 변수에 null 을 넣고 해당 String 변수의 값에 접근했을 때 NullPointerException 서버 에러가 발생한다.
전역적으로 @ControllerAdvice 를 사용했고 @ExceptionHandler 에 NullPointerException.class 를 설정했다.
결과
모델 속성 추가(@ModelAttribute)
공통적으로 Front 에 Model 값을 전달해야 할때 사용한다.
package com.obo.controller.global;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
@ControllerAdvice
public class GlobalExceptionController {
@ModelAttribute("testValue")
public String testValue() {
return "testModelValue";
}
}
window.addEventListener("DOMContentLoaded", (event) => {
console.log('global model : ',/*[[${testValue}]]*/ "");
});
testValue 는 @ModelAttribute 에 설정한 변수명이 된다.
본인은 Thymeleaf 를 사용했기 때문에 /*[[${}]]*/ 문법을 사용했고 아래 결과를 정상적으로 받을 수 있다.
결과
사용하게된 계기
본인은 공통적으로 사용하는 변수값을 체크하여 특정 View 에 공통적으로 데이터를 넘겨야 할 상황이 있었다.
그래서 @ControllerAdvice 를 사용했다.
@ControllerAdvice 와 @ModelAttribute 어노테이션을 사용하여 요청 별로 각 Pakcage 경로마다
공통 속성을 추가해야 할 상황에 적절하다.
아래와 같이 CommonControllerAdvice 라는 클래스를 생성한다.
package com.youth.market.system.handler;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
@ControllerAdvice(basePackages = {"com.youth.market.controller.common"})
public class CommonControllerAdvice {
@ModelAttribute("isModelTest")
public String addTest(HttpServletRequest request) {
return "test";
}
}
@ControllerAdvice(basePackages = {"com.youth.market.controller.common"})
위와 같이 @ControllerAdvice 의 basePakcages 속성을 통해 공통적으로 값을 넘길 클래스들의 Pakcage 경로를
설정할 수 있다.
아래는 ControllerAdvice 어노테이션 인터페이스이다.
@ModelAttribute("isModelTest")
public String addTest(HttpServletRequest request) {
return "test";
}
@ModelAttribute 를 통해 설정한 basePakcages 에 공통 데이터를 전달할 수 있다.
isModelTest 라는 변수 이름으로 test 라는 String 문자열이 공통으로 전달된다.
결과
본인은 Thymeleaf 템플릿 엔진을 사용했으므로 /*[[${isModelTest}]]*/ ""; 형태이다.