1. 程式人生 > >SpringMVC(九)控制器通知

SpringMVC(九)控制器通知

SpringMVC(九)控制器通知

在spring AOP中,可以通過通知來增強Bean的功能。同樣地,spring MVC也可以給控制器增加通知,於是在控制器方法的前後和異常發生時去執行不同的處理

這裡涉及4個註解,分別是@ControllerAdvice@InitBinderExceptionHandler@ModelAttribute

  • @ControllerAdvice:定義一個控制器的通知類,允許定義一些關於增強控制器的各類通知和限定增強哪些控制器功能等。
  • @InitBinder:定義控制器引數繫結規則,如轉換規則,格式化等,它會在引數轉換之前執行。
  • @ExceptionHandler:定義控制器發生異常後的操作。一般來說,發生異常後,可以挑戰到指定的友好頁面,以避免使用者使用的不友好。
  • @ModelAtrribute:可以在控制器的方法執行之前,對資料模型進行操作。

下面通過程式碼來看這些註解的使用方法

package com.lay.mvc.controller.advice;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.
web.bind.annotation.ModelAttribute; import java.text.SimpleDateFormat; import java.util.Date; /** * @Description: 定義控制器通知 * @Author: lay * @Date: Created in 17:07 2018/11/15 * @Modified By:IntelliJ IDEA */ @ControllerAdvice( //指定攔截的包 basePackages = {"com.lay.mvc.controller.advice.test.*"}, //限定被標註@Controller的類才被攔截 annotations = Controller.class) public class MyControllerAdvice { //繫結格式化參、引數轉換規則和增加驗證器 @InitBinder public void initDataBinder(WebDataBinder binder){ //自定義日期編輯器,限定格式為yyyy-Mm-dd,且引數不允許為空 CustomDateEditor dateEditor=new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),false); //註冊自定義日期編輯其 binder.registerCustomEditor(Date.class,dateEditor); } //在控制器之前線執行,可以初始化資料模型 @ModelAttribute public void projectModel(Model model){ model.addAttribute("projectName","spring_mvc"); } // 異常處理,使得被攔截的控制器發生異常時,都能用相同的檢視響應 @ExceptionHandler(value = Exception.class) public String exception(Model model ,Exception ex){ //給資料模型增加異常訊息 model.addAttribute("exception_message",ex.getMessage()); //返回異常檢視 return "exception"; } }
  • @ControllerAdvice:標明一個控制器的通知類,這個註解也標註了@Controller,所以它會在Spring Ioc容器中自動掃描和裝配。它的配置項basePackages配置的是包名限制,也就是符合該配置的包控制器才會被這個控制器通知所攔截,而annotaions得配置項則是在原有包名限定的基礎上再新增被標註為@Controller的類才會被攔截。
  • @InitBinder:是一個控制器引數轉換前被執行的程式碼。這裡的WebDataBinder引數物件是spring mvc會自動生成的引數,這裡定義了日期(Date)型別的引數,採用了限定格式"yyyy-MM-dd",則不再需要加入@DateTimeFormat對格式再進行指定,直接採用”yyyy-MM-dd“格式傳輸日期引數即可。
  • @ModelAtrribute:是一個數據模型的註解。它在執行控制器方法前被執行,程式碼中增加了一個字串,因此在控制器方法中可以獲取它。
  • @ExceptionHandler:配置項為Exception,它可以攔截所有控制器發生的異常。這裡的Exception引數是Spring MVC執行控制器發生異常時傳遞的,而在方法中,給資料模型添加了異常資訊,然後返回一個字串exception,這個字元指向了對應的檢視。

為了測試控制器通知,我們寫一個測試的控制器

TestController

package com.lay.mvc.controller.advice.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.thymeleaf.util.DateUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * @Description:
 * @Author: lay
 * @Date: Created in 17:09 2018/11/15
 * @Modified By:IntelliJ IDEA
 */
@Controller
@RequestMapping("/advice")
public class TestController {
    @GetMapping("/test")
    public String test(Date date, ModelMap modelMap){
        //從資料模型中獲取資料
        String projectName = (String) modelMap.get("projectName");
        System.out.println(projectName);
        //列印日期引數
        System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(date));
        //丟擲異常,這樣轉到控制器異常通知
        throw new RuntimeException("異常,跳轉到控制器通知的異常資訊裡");
    }

}

展示異常頁面

exception.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>異常頁面</title>
</head>
<body>
<h1 th:text="${exception_message}"></h1>
</body>
</html>