spring boot 全局异常处理的实现(@ExceptionHandler),以及@InitBinder、@ModelAttribute的作用

spring boot 异常处理:
      在spring 3.2中,新增了@ControllerAdvice 注解,这个注解注释的类实现控制器增强的功能,在其中可以定义@ExceptionHandler、@InitBinder、@ModelAttribute,
    并应用到所有@RequestMapping注释的方法中。
1.@ExceptionHandler实现全局异常处理 1)在启动类所在的包或其子包中定义全局异常处理类: @ControllerAdvice //"控制器增强"注解 public class ExceptionHander { @ExceptionHandler(Exception.class) //用于注释异常处理类,value属性指定需要拦截的异常类型 @ResponseBody //和controller方法上的用法一样,会将方法中的返回值转json后返回给客户端 public Map<String, Object> errorHandler(Exception e) { //捕获异常并获取异常处理对象 Map<String, Object> result = new HashMap<String, Object>(); result.put("code", "0"); result.put("msg", e.getMessage()); //获取异常信息 return result; //将异常信息响应给浏览器 } } 上面的errorHandler()会捕获到所有被@RequestMapping注释的方法中所抛出的异常,并获取到异常处理对象,异常对象会被赋值给参数e。在此方法中处理异常并将处理结果响应给客户端 2)如在controller中: @RequestMapping("/hello") public String sayHello() { int a=1/0; //程序在这里会出异常 return "hello,spring boot"; } 访问上面的controller时,会抛出/0 异常,这个异常将被全局异常处理类捕获和处理,并将结果响应,响应结果: {"msg":"/ by zero","code":"0"} 2.@ExceptionHandler实现自定义全局异常处理类 在实际应用中,往往需要对程序中的异常进行自定义处理: 1)自定义异常类: public class MyException extends RuntimeException { //继承RuntimeException private String code; private String msg; public MyException(String code, String msg) { super(); this.code = code; this.msg = msg; } //getter & setter方法 ... } 2)在上面被@ControllerAdvice注释的类中添加方法: @ControllerAdvice public class ExceptionHander { @ExceptionHandler(Exception.class) @ResponseBody public Map<String, Object> errorHandler(Exception e) { //--方法1 Map<String, Object> result = new HashMap<String, Object>(); result.put("code", "0"); result.put("msg", e.getMessage()); return result; } @ExceptionHandler(MyException.class) //在这里将value属性改为自定义的异常类,表示将拦截MyException异常 @ResponseBody public Map<String, Object> errorHandler(MyException e) { //参数也改为自定义的异常类 --方法2 Map<String, Object> result = new HashMap<String, Object>(); result.put("code", e.getCode()); result.put("msg", e.getMsg()); return result; } } 当程序抛出自定义异常时,将会被方法2捕获并处理,如果是抛出其他异常,将被方法1捕获并处理 3)如,在Controller中抛出自定义异常和其他异常 1)抛出自定义异常 @RequestMapping("/hello") public String sayHello() { throw new MyException("0", "自定义全局异常"); //抛出自定义异常 } 程序运行时抛出自定义异常,会被捕获并处理,响应结果: {"msg":"自定义全局异常","code":"0"} 2)抛出其他异常: @RequestMapping("/hello") public String sayHello() { int a=1/0; //程序在这里会出异常 return "hello,spring boot"; } 抛出的异常不是自定义异常,将被@ExceptionHandler(Exception.class)注释的方法拦截并处理,响应结果: {"msg":"/ by zero","code":"0"} 3.被@ControllerAdvice注释的类中@InitBinder、@ModelAttribute的作用 @InitBinder 在其执行之前初始化数据绑定器 @ModelAttribute 1)@ModelAttribute 1)在@ControllerAdvice注释的类中添加方法: @ModelAttribute public void addAtr(Model model){ //参数为model对象 model.addAttribute("globalAtt", "全局属性"); //添加属性 } 2)在controller中能获取到上面添加的属性,两种方法获取: 方法1: @RequestMapping("/hello") public String sayHello(@ModelAttribute("globalAtt") String author) { return author; } 方法2: @RequestMapping("/hello") public String sayHello(ModelMap modelMap) { //通过ModelMap获取 return (String) modelMap.get("globalAtt"); } 响应结果均为: 全局属性 2)@InitBinder 这个注解用于初始化数据绑定器。数据绑定器就是springMVC用于进行参数绑定的组件。 当请求中某些数据如日期数据不能实现自动绑定时,可以通过这个 注解对数据绑定器进行初始化: 如: 1)初始化数据绑定器 @ControllerAdvice public class ExceptionHander { @InitBinder //初始化数据绑定器 public void InitBinder(WebDataBinder binder){ SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); CustomDateEditor editor=new CustomDateEditor(sdf, false); //定义日期编辑器,编辑器都是PropertyEditorSupport的子类 //可以根据需要定义其它的编辑器 binder.registerCustomEditor(Date.class, editor); //注册编辑器,这里的第一个参数为要绑定的参数类型 } } 2)controller方法: @RequestMapping("/hello") public String sayHello(Date date) { //这里需要绑定一个日期参数,无法自动绑定,必须借助编辑器 return new SimpleDateFormat("yyyy-MM-dd").format(date); } 3)访问路径: http://localhost:8080/springboot/hello?date=1992-12-18 //这里传入一个日期 字符串 响应结果: 1992-12-18 流程:程序启动时会自动注册日期转化的编辑器。程序进行参数绑定时,如果发现要将参数绑定到一个Date对象,就会获取到我们初始化的编辑器CustomDateEditor, 通过这个编辑器将参数中的日期字符串转化为日期对象,并实现参数绑定。 注意,@initBinder注解也可以放在Controller类中使用。如果这样使用,这个编辑器的作用域只在当前的controller中 如: @RestController @RequestMapping("/springboot") public class DemoController { @RequestMapping("/hello") public String sayHello( Date date) { return new SimpleDateFormat("yyyy-MM-dd").format(date); } @InitBinder public void initb(WebDataBinder binder){ //直接放在controller 类中,只作用于当前的controller SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); CustomDateEditor editor=new CustomDateEditor(sdf, false); binder.registerCustomEditor(Date.class, editor); } }

 

posted @ 2018-12-09 16:22  foreast  阅读(5096)  评论(0编辑  收藏  举报