1, Introduction
aop can be used for global processing in spring MVC. Here we introduce another way, with the help of springMvc's controlleradvce annotation and ErrorController interface.
2, ControllerAdvice annotation
@Controlleradvice (directly return the request body, you can use @ RestControllerAdvice) to process the controller globally, usually with the help of @ ExceptionHandler, @ InitBinder, @ ModelAttribute.
2.1 @ExceptionHandler@ ExceptionHandler is used to handle controller exceptions globally. An example is as follows:
2.1.1 useDefine the controller exception capture class. The class is decorated with @ ControllerAdvice annotation, and the handling method is decorated with @ ExceptionHandler.
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class ExceptionControllerAdvice { //Catch all exceptions by annotating @ ExceptionHandler @ResponseBody @ExceptionHandler(value = {Exception.class}) public Object exceptionDispose(Exception e, HttpServletRequest req, HttpServletResponse res) { Map<String, Object> result = new HashMap<>(); result.put("exception", e.getClass().getName()); result.put("uri", req.getRequestURI()); return result; } }
Define controllers that throw exceptions:
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("ex") public class ExceptionController { //abnormal @RequestMapping("exception") public Object exception(String exClassName) throws Exception { throw (Exception) Class.forName(exClassName).newInstance(); } }2.1.2 testing
Request:
### Null pointer exception test GET http://localhost:9090/ex/exception?id=002&exClassName=java.lang.NullPointerException Accept: application/json
Response:
{ "exception": "java.lang.NullPointerException", "uri": "/ex/exception" }2.2 @ModelAttribute
@ModelAttribute is used for global parameter binding, which can bind parameters to all requests in advance. An example is as follows:
2.2.1 useDefine the binding parameter processing class. The class is decorated with @ ControllerAdvice annotation, and the processing method is decorated with @ modelattribute.
import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ModelAttribute; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.UUID; @ControllerAdvice public class ModelAttributeControllerAdvice { //Catch all exceptions by annotating @ ExceptionHandler @ModelAttribute public void modelAttributeDispose(Model model, HttpServletRequest req, HttpServletResponse res) { model.addAttribute("token", UUID.randomUUID()); } }
Define the test controller:
import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; @RestController @RequestMapping("ma") public class ModelAttributeController { //Parameter binding @RequestMapping("modelAttribute") public Object modelAttribute(Model model, HttpServletRequest req, HttpServletResponse res) throws Exception { return new HashMap<>(model.asMap()); } }2.2.2 testing
Request:
### Global parameter test GET http://localhost:9090/ma/modelAttribute?id=003 Accept: application/json
Response:
{ "token": "9143f492-e501-4c4f-8c17-637ed7bd048a" }2.3 @InitBinder
@InitBinder is used for parameter binding processing, and can transform parameters.
2.3.1 useDefine the parameter handling class. The class is decorated with @ ControllerAdvice annotation, and the processing method is decorated with @ InitBinder.
import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.InitBinder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; @ControllerAdvice public class InitBinderControllerAdvice { private DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); @InitBinder public void initBinder(WebDataBinder wdb, HttpServletRequest req, HttpServletResponse res) { CustomDateEditor cde = new CustomDateEditor(df, true); wdb.registerCustomEditor(Date.class, cde); } }
Define the parameter binding transformation test controller.
import org.apache.commons.lang3.time.DateFormatUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Date; @RestController @RequestMapping("ib") public class InitBinderController { //Parameter conversion binding @RequestMapping("initBind") public Object initBind(Date dt) throws Exception { return DateFormatUtils.format(dt, "yyyy-MM-dd"); } }2.3.2 testing
Request:
### Global parameter test GET http://localhost:9090/ib/initBind?dt=2020-06-29 Accept: application/json
Response:
2020-06-29
3, ErrorController interface
The ErrorController interface can capture and process the request errors that have not yet entered the controller. In use, the getErrorPath method is implemented by inheriting the ErrorController interface, specifying the error processing path, and then processing in the error path controller method. An example is as follows:
3.1 examples of useDefine the error handling controller class, inherit ErrorController, and specify the error handling path in the implementation method getErrorPath.
import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @RestController public class JsonErrorController implements ErrorController { @Override public String getErrorPath() { //Specify error handling path return "/error"; } //error handling @RequestMapping("error") public Object errorDispose(HttpServletRequest req) { Map<String, Object> result = new HashMap<>(); result.put("code", req.getAttribute("javax.servlet.error.status_code")); result.put("uri", req.getRequestURI()); result.put("param", req.getParameterMap()); return result; } }3.2 testing
Request:
### Error capture of test input without address GET http://localhost:9090/xx?id=001 Accept: application/json
Response:
{ "code": 404, "param": { "id": [ "001" ] }, "uri": "/error" }