WebMvcConfigurer
WebMvcConfigurer
是用來全局制定 Spring Boot 的 mvc 特性。開發者通過實現 WebMvcConfigurer 接口來配置應用的 MVC 全局特性。
@Configuration
public class MvcConfigurer implements WebMvcConfigurer {
//攔截器
public void addInterceptors (InterceptorRegistry registry) {
}
// 跨域訪問配置
public void addCorsMappings(CorsRegistry registry) {
}
//格式化
public void addFormatters (FormatterRegistry registry) {
}
// URI 到視圖的映射
public void addViewControllers(ViewControllerRegistry registry) {
}
// 其他更多全局定制接口
}
攔截器
通過 addInterceptors
方法可以設置多個攔截器,比如對特定的 URI 設定攔截器以檢查用戶是否登錄,打印處理用戶請求耗費的時間等。
@Autowired
private SessionHandlerInterceptor sessionHandlerInterceptor;
public void addInterceptors(InterceptorRegistry registry) {
// 增加一個攔截器,檢查會話, URL 以 admin 開頭的都適用此攔截器
registry.addInterceptor(sessionHandlerInterceptor).addPathPatterns("/admin/**");
}
@Component
class SessionHandlerInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
User user = (User) requset.getSession().getAttribute("user");
if(user == null) {
//沒有登錄,重定向到 login.html
response.sendRedirect("/login.html");
return false;
}
return true;
//在處理器之前執行的前置方法,這樣 Spring MVC 可以在進入處理器前處理一些方法。注意,他會返回一個 boolean 值,會影響到后面Spring MVC 的流程。
}
publica void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// controller 方法處理完畢,頁面渲染之前調用此方法。比如可以在這里將渲染的視圖名稱更改為其他視圖。
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception {
// 頁面渲染完畢后調用此方法,通常用來接觸某些資源。
}
}
上邊這段代碼,我們在 MvcConfigurer 總實現了 addInterceptors
方法,並對訪問地址 /admin/**
添加了一個攔截器。
攔截器,有以下三個方法需要覆蓋實現
preHandle
,在調用 Controller
方法前會調用此方法
postHandle
,在調用 Controller
方法結束后、頁面渲染之前調用此方法,比如可以在這里將渲染的視圖名稱更改為其他視圖名
afterCompletion
,頁面渲染完畢后調用此方法。
在進入處理器之前或者之后處理一些邏輯,或者在渲染視圖之后處理一些邏輯,都是允許的。有時候要自己實現一些攔截器,以加強請求的功能。注意,當前置方法返回 false 時,就不會再執行后邊的邏輯了。
在正常情況下,Sping 會先從第一個攔截器開始進入前置方法,這樣前置方法是按配置順行執行的,然后運行處理代碼,最后運行后置方法。注意,后置方法和完成方法則是按照配置逆序運行的,這和責任鏈模式運行順序是一致的,掌握了責任鏈模式這個順序就好理解了。
注意,當其中一個 preHandle 方法返回為false后,按配置順序,后面的 preHandle 方法都不會運行了,而控制器和所有后置方法 postHandle也不會再運行。
跨域訪問
處於安全的考慮,瀏覽器會禁止 AJAX 訪問不同域的地址。
Spring Boot 提供了對 CORS 的支持,可以實現 addCorsMappings
接口來添加特定的配置:
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
允許所有跨域訪問,或者更為精細的控制
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://doain2.com")
.allowedMethods("POST","GET");
}
跨域原理簡單理解就是發起跨域請求的時候,瀏覽器會對請求域返回的響應信息檢查HTTP頭,如果Access-Control-Allow-Origin 包含了自身域,則表示允許訪問。否則報錯,這就是 allowedOrigins 的作用。
注冊Controller
應用有時候沒有必要為一個 URL 制定一個Controller方法,可以直接將 URI 請求轉到對應的模版渲染上。可以直接通過 ViewControllerRegistry
注冊一個:
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index.html").setViewName("/index.html");
registry.addRedirectViewController("/**/*.do","/index.html");
}