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