Spring进阶之@ControllerAdvice与统一异常处理 待我称王封你为后i 2022-02-27 01:05 223阅读 0赞 ## @ControllerAdvice ## Spring源码中有关`@ControllerAdvice`的注解如下: > Specialization of \{@link Component @Component\} for classes that declare \{@link ExceptionHandler @ExceptionHandler\}, \{@link InitBinder @InitBinder\}, or \{@link ModelAttribute @ModelAttribute\} methods to be shared across multiple \{@code @Controller\} classes. 理解: `@ControllerAdvice`是一个特殊的`@Component`,用于标识一个类,这个类中被以下三种注解标识的方法:`@ExceptionHandler`,`@InitBinder`,`@ModelAttribute`,将作用于所有的`@Controller`类的接口上。 那么,这个三个注解分别是什么意思,起到什么作用呢? ## @InitBinder ## > Annotation that identifies methods which initialize the \{@link org.springframework.web.bind.WebDataBinder\} which will be used for populating command and form object arguments of annotated handler methods. > Such init-binder methods support all arguments that \{@link RequestMapping\} supports, except for command/form objects and corresponding validation result objects. Init-binder methods must not have a return value; they are usually declared as \{@code void\}. 作用:注册属性编辑器,对HTTP请求参数进行处理,再绑定到对应的接口,比如格式化的时间转换等。应用于单个@Controller类的方法上时,仅对该类里的接口有效。与@ControllerAdvice组合使用可全局生效。 示例: @ControllerAdvice public class ActionAdvice { @InitBinder public void handleException(WebDataBinder binder) { binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss")); } } ## @ExceptionHandler ## 作用:统一异常处理,也可以指定要处理的异常类型 示例: @ControllerAdvice public class ActionAdvice { @ExceptionHandler(Exception.class) @ResponseBody @ResponseStatus(HttpStatus.OK) public Map handleException(Exception ex) { Map<String, Object> map = new HashMap<>(); map.put("code", 400); map.put("msg", ex.toString()); return map; } } ## @ModelAttribute ## 作用:绑定数据 示例: @ControllerAdvice public class ActionAdvice { @ModelAttribute public void handleException(Model model) { model.addAttribute("user", "zfh"); } } 在接口中获取前面绑定的参数: @RestController public class BasicController { @GetMapping(value = "index") public Map index(@ModelAttribute("user") String user) { //... } } -------------------- 完整示例代码: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.format.datetime.DateFormatter; import org.springframework.http.HttpStatus; import org.springframework.ui.Model; import org.springframework.validation.Validator; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; /** * 统一异常处理 * @author zfh * @version 1.0 * @since 2019/1/4 15:23 */ @ControllerAdvice public class ControllerExceptionHandler { private Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class); @InitBinder public void initMyBinder(WebDataBinder binder) { // 添加对日期的统一处理 //binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd")); binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss")); // 添加表单验证 //binder.addValidators(); } @ModelAttribute public void addMyAttribute(Model model) { model.addAttribute("user", "zfh"); // 在@RequestMapping的接口中使用@ModelAttribute("name") Object name获取 } @ExceptionHandler(value = Exception.class) @ResponseStatus(HttpStatus.OK) @ResponseBody // 如果使用了@RestControllerAdvice,这里就不需要@ResponseBody了 public Map handler(Exception ex) { logger.error("统一异常处理", ex); Map<String, Object> map = new HashMap<>(); map.put("code", 400); map.put("msg", ex); return map; } } 测试接口: @RestController public class TestAction { @GetMapping(value = "testAdvice") public JsonResult testAdvice(@ModelAttribute("user") String user, Date date) throws Exception { System.out.println("user: " + user); System.out.println("date: " + date); throw new Exception("直接抛出异常"); } } -------------------- ## 高阶应用–格式化时间转Date ## 使用`@ControllerAdvice` \+ `@InitBinder`,可将http请求参数中的时间自动转换成Date类型。 @InitBinder public void initBinder(WebDataBinder binder) { GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService(); if (genericConversionService != null) { genericConversionService.addConverter(new DateConverter()); } } 自定义的时间类型转换器: import org.springframework.core.convert.converter.Converter; import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; import java.util.Date; /** * 日期转换类 * 将标准日期、标准日期时间、时间戳转换成Date类型 */ public class DateConverter implements Converter<String, Date> { private static final String dateFormat = "yyyy-MM-dd HH:mm:ss"; private static final String shortDateFormat = "yyyy-MM-dd"; private static final String timeStampFormat = "^\\d+$"; @Override public Date convert(String value) { if(StringUtils.isEmpty(value)) { return null; } value = value.trim(); try { if (value.contains("-")) { SimpleDateFormat formatter; if (value.contains(":")) { formatter = new SimpleDateFormat(dateFormat); } else { formatter = new SimpleDateFormat(shortDateFormat); } return formatter.parse(value); } else if (value.matches(timeStampFormat)) { Long lDate = new Long(value); return new Date(lDate); } } catch (Exception e) { throw new RuntimeException(String.format("parser %s to Date fail", value)); } throw new RuntimeException(String.format("parser %s to Date fail", value)); } } 扩展: `@RestControllerAdvice` = `@ControllerAdvice` \+ `@ResponseBody` -------------------- 参考: > 1. [Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理][Spring Boot _ControllerAdvice] > 2. [SpringMVC重要注解(二)@ControllerAdvice][SpringMVC_ControllerAdvice] > 3. [精通Spring Boot —— 第十五篇:使用@ControllerAdvice处理异常][Spring Boot _ _ControllerAdvice] > 4. [@InitBinder][InitBinder] > 5. [SpringMVC中利用@InitBinder来对页面数据进行解析绑定][SpringMVC_InitBinder] [Spring Boot _ControllerAdvice]: https://www.cnblogs.com/magicalSam/p/7198420.html [SpringMVC_ControllerAdvice]: https://blog.csdn.net/w372426096/article/details/78429141 [Spring Boot _ _ControllerAdvice]: https://yq.aliyun.com/articles/647428 [InitBinder]: https://blog.csdn.net/zero__007/article/details/80466392 [SpringMVC_InitBinder]: https://www.cnblogs.com/heyonggang/p/6186633.html
相关 @ControllerAdvice统一处理异常 [@ControllerAdvice实现优雅地处理异常][ControllerAdvice] [ControllerAdvice]: https://blog.csdn.n 小鱼儿/ 2022年11月22日 05:16/ 0 赞/ 108 阅读
相关 spring使用@ExceptionHandler、@ControllerAdvice统一异常处理 1. 自己定义的异常,继承RuntimeException。可以建个exception包,专门放自定义异常。自定义的异常用来描述自己程序中特有的异常。 朴灿烈づ我的快乐病毒、/ 2022年06月17日 13:52/ 0 赞/ 160 阅读
相关 @controllerAdvice 统一处理异常(spring-mvc) @controllerAdvice 统一处理异常(spring-mvc) 如题,利用controllerAdvice注解进行异常的统一处理。 好,下面上货。 墨蓝/ 2022年06月13日 19:59/ 0 赞/ 176 阅读
相关 SpringBoot进阶之统一异常处理(含源码) > 浅谈异常处理 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个 男娘i/ 2022年06月09日 12:07/ 0 赞/ 138 阅读
相关 SpringBoot 统一异常处理--- @ControllerAdvice 使用 > 参考慕课网地址: Aop之统一异常处理 [http://www.imooc.com/learn/810][http_www.imooc.com_learn_810] S 雨点打透心脏的1/2处/ 2022年06月04日 02:52/ 0 赞/ 166 阅读
相关 spring统一异常处理 Spring提供了同意的异常处理注解,用户只需要在错误的时候提示信息即可 1. 实现方式: 在类上添加@ControllerAdvic 川长思鸟来/ 2022年05月18日 23:52/ 0 赞/ 159 阅读
相关 Spring统一异常处理 1. 先回顾一下Java的异常体系 参考文章:[Java中的异常和处理详解][Java] 下面几段关于异常的介绍就是来自上面这篇文章(感谢文章作者),为了看着方便,这里直接 短命女/ 2022年05月16日 15:52/ 0 赞/ 179 阅读
相关 @ControllerAdvice 全局异常处理 [ControllerAdvice 文档][ControllerAdvice] 在spring 3.2中,新增了@ControllerAdvice 注解,它通常用于定义 迈不过友情╰/ 2022年04月25日 01:36/ 0 赞/ 204 阅读
相关 Spring进阶之@ControllerAdvice与统一异常处理 @ControllerAdvice Spring源码中有关`@ControllerAdvice`的注解如下: > Specialization of \{@link C 待我称王封你为后i/ 2022年02月27日 01:05/ 0 赞/ 224 阅读
还没有评论,来说两句吧...