@ControllerAdvice is an annotation in Spring Framework that is used to handle exceptions globally across multiple controllers in a Spring MVC application.
By using this annotation, you can define methods that will be applied to all controllers or specific controllers to handle exceptions thrown during request processing. These methods can perform actions such as logging the exception, customizing the error response, or redirecting to an error page.
Here’s a simple example of how to use @ControllerAdvice in a Spring MVC application:
- Create a new class and annotate it with @ControllerAdvice . This class will handle exceptions globally across multiple controllers.
@ControllerAdvice
public class GlobalExceptionHandler {
// Exception handling methods go here
}
- Define methods within the GlobalExceptionHandler class to handle specific exceptions. These methods should be annotated with @ExceptionHandler and specify the exception class they are meant to handle.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
// Handle the exception here
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred");
}
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<String> handleNotFoundException(NotFoundException ex) {
// Handle the NotFoundException here
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Resource not found");
}
// Add more exception handling methods as needed
}
- Customize the exception handling logic within each method. You can log the exception, modify the response, or perform any other necessary actions.
- Make sure to import the necessary classes, such as ResponseEntity and HttpStatus .
That’s it! With this setup, any exceptions thrown within your controllers will be caught by the corresponding @ExceptionHandler methods in the GlobalExceptionHandler class. You can then handle the exceptions and return appropriate responses to the client.
使用场景1:修改 返回值
通过实现接口ResponseBodyAdvice
来修改返回值,并直接作为 ResponseBody 类型处理器 的返回值。
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.Map;
@ControllerAdvice
public class HelloResponseBodyAdvice implements ResponseBodyAdvice<Map<String, Object>> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Map<String, Object> beforeBodyWrite(Map<String, Object> body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
// 修改返回值
System.out.println("origin map: " + body);
body.put("msg", "hello");
return body;
}
}
验证
@RestController
@RequestMapping("/test")
public class ResponseBodyAdviceController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public Map<String, Object> hello() {
Map<String, Object> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
return map;
}
}
测试中总结
如果存在多个实现接口ResponseBodyAdvice
的类,则均执行,且按照类名字母降序的顺序执行。比如
HelloResponseBodyAdvice
比 PracResponseBodyAdvice
先执行,
APracResponseBodyAdvice
比 HelloResponseBodyAdvice
先执行。