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); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM