WebMvcConfigurer 源码:
public interface WebMvcConfigurer {
/**
*访问路径处理。比如PathMatchConfigurer的setUseTrailingSlashMatch()方法
*默认为true,匹配url不考虑结尾的"/",如 “/users”和“/users/”都可以匹配
*/
default void configurePathMatch(PathMatchConfigurer configurer) {
}
/**
*Configure content negotiation options,配置内容协商选项
*也就是一个请求路径返回多种数据格式
*/
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
/**
*处理异步请求的。只能设置两个值
*一个超时时间(毫秒,Tomcat下默认是10000毫秒,即10秒)
*还有一个是AsyncTaskExecutor,异步任务执行器
*/
default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
/**
*默认静态资源处理器
*/
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}
/**
*注册自定义转化器
*/
default void addFormatters(FormatterRegistry registry) {
}
/**
*自定义写拦截器
*/
default void addInterceptors(InterceptorRegistry registry) {
}
/**
*自定义资源映射
*/
default void addResourceHandlers(ResourceHandlerRegistry registry) {
}
/**
*设置跨域
*/
default void addCorsMappings(CorsRegistry registry) {
}
/**
*视图跳转控制器
*/
default void addViewControllers(ViewControllerRegistry registry) {
}
/**
*配置视图解析
*/
default void configureViewResolvers(ViewResolverRegistry registry) {
}
/**
*添加自定义方法参数处理器
*/
default void addArgumentResolvers(List resolvers) {
}
/**
*添加自定义返回结果处理器
*/
default void addReturnValueHandlers(List handlers) {
}
/**
*配置消息转换器。重载会覆盖默认注册的HttpMessageConverter
*/
default void configureMessageConverters(List> converters) {
}
/**
*配置消息转换器。仅添加一个自定义的HttpMessageConverter.
*/
default void extendMessageConverters(List> converters) {
}
/**
*配置异常转换器
*/
default void configureHandlerExceptionResolvers(List resolvers) {
}
/**
*添加异常转化器
*/
default void extendHandlerExceptionResolvers(List resolvers) {
}
@Nullable
default Validator getValidator() {
return null;
}
@Nullable
default MessageCodesResolver getMessageCodesResolver() {
return null;
}
}
使用方法
这里的“@EnableAutoConfiguration中的设置”是指,读取 application.properties 或 application.yml 文件中的配置
例子:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping("/**")
// 设置允许跨域请求的域名
.allowedOrigins("*")
// 是否允许证书
.allowCredentials(true)
// 设置允许的方法
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
// 设置允许的header属性
.allowedHeaders("*")
// 跨域允许时间
.maxAge(3600);
}
}
CorsRegistry源码
public class CorsRegistry {
private final List registrations = new ArrayList<>();
public CorsRegistration addMapping(String pathPattern) {
CorsRegistration registration = new CorsRegistration(pathPattern);
this.registrations.add(registration);
return registration;
}
protected Map getCorsConfigurations() {
Map configs = new LinkedHashMap<>(this.registrations.size());
for (CorsRegistration registration : this.registrations) {
configs.put(registration.getPathPattern(), registration.getCorsConfiguration());
}
return configs;
}
}
CorsRegistry 有个属性registrations ,可以根据不同的项目路径进行定制访问行为
getCorsConfigurations(),这个方法是获取所有CorsConfiguration的Map集合,key值为传入路径pathPattern
egistry对象addMapping()增加完传入路径pathPattern之后,return了一个CorsRegistration对象,是进行更多的配置
CorsRegistration源码
public class CorsRegistration {
//允许跨域的路径
private final String pathPattern;
//配置信息实体类
private final CorsConfiguration config;
//构造方法
public CorsRegistration(String pathPattern) {
this.pathPattern = pathPattern;
// Same implicit default values as the @CrossOrigin annotation + allows simple methods
//与@CrossOrigin注释+相同的隐式默认值允许使用简单方法
//@CrossOrigin注解可以作用于方法或者类上,实现局部跨域
this.config = new CorsConfiguration().applyPermitDefaultValues();
}
//允许哪些源网站访问,默认所有
public CorsRegistration allowedOrigins(String... origins) {
this.config.setAllowedOrigins(Arrays.asList(origins));
return this;
}
//允许何种方式访问,默认简单方式,即:GET,HEAD,POST
public CorsRegistration allowedMethods(String... methods) {
this.config.setAllowedMethods(Arrays.asList(methods));
return this;
}
//设置访问header,默认所有
public CorsRegistration allowedHeaders(String... headers) {
this.config.setAllowedHeaders(Arrays.asList(headers));
return this;
}
//设置response headers,默认没有(什么都不设置)
public CorsRegistration exposedHeaders(String... headers) {
this.config.setExposedHeaders(Arrays.asList(headers));
return this;
}
//是否浏览器应该发送credentials,例如cookies Access-Control-Allow-Credentials
public CorsRegistration allowCredentials(boolean allowCredentials) {
this.config.setAllowCredentials(allowCredentials);
return this;
}
//设置等待时间,默认1800秒
public CorsRegistration maxAge(long maxAge) {
this.config.setMaxAge(maxAge);
return this;
}
protected String getPathPattern() {
return this.pathPattern;
}
protected CorsConfiguration getCorsConfiguration() {
return this.config;
}
}
@Configuration
public class WebConfigurer
implements WebMvcConfigurer
{
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**");
}
/**
*继承了HandlerInterceptorAdapter的拦截器
*/
@Bean
public LoginInterceptor LoginInterceptor() {
return new LoginInterceptor();
}
}
/**
*如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面
*在这里配置之后就不需要了
*直接访问http://localhost:8080/toLogin 可以直接访问 login.html
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/toLogin").setViewName("login");
}
重写addViewControllers,并不会覆盖WebMvcAutoConfiguration中的addViewControllers(在此方法中,Spring Boot将“/”映射至index.html) 这也就意味着我们自己的配置和Spring Boot的自动配置同时有效
/**
* 配置静态访问资源
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/public-resources/");
}
访问自定义public-resources文件夹中的test.jpg 图片的地址为
http://localhost:8080/resources/test.jpg
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
springMVC是通过DispatcherServlet将请求的URL映射到对应的控制器方法上,传统的配置DispatcherServlet的方式是配置在web.xml文件中
但是在servlet3.0的环境中,servlet容器会在类路径中查找javax.servlet.ServletContainerInitializer接口的类,如果能发现,就会用来配置servlet容器。
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/view/", ".jsp");
}
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// 是否通过请求Url的扩展名来决定media type
configurer.favorPathExtension(true)
// 不检查Accept请求头
.ignoreAcceptHeader(true)
// 设置查询参数名,当favorParameter(true)时使用。
.parameterName("mediaType")
//设置要使用的默认内容类型, 默认情况下不设置此选项
.defaultContentType(MediaType.TEXT_HTML)
// 请求以.html结尾的会被当成MediaType.TEXT_HTML
.mediaType("html", MediaType.TEXT_HTML)
// 请求以.json结尾的会被当成MediaType.APPLICATION_JSON
.mediaType("json", MediaType.APPLICATION_JSON);
}
有三个方法
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
}
preHandle在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制等处理;
返回true将继续执行,如果返回false,将不进行执行。一般用于登录校验。
postHandle在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView;
afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面),可以根据ex是否为null判断是否发生了异常,进行日志记录;