SpringBoot配置接⼝WebMvcConfigurer
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.fig.annotation;
import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.verter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.hod.support.HandlerMethodArgumentResolver;
import org.hod.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
public interface WebMvcConfigurer {
void configurePathMatch(PathMatchConfigurer var1);
void configureContentNegotiation(ContentNegotiationConfigurer var1);
void configureAsyncSupport(AsyncSupportConfigurer var1);
void configureDefaultServletHandling(DefaultServletHandlerConfigurer var1);
void addFormatters(FormatterRegistry var1);
void addInterceptors(InterceptorRegistry var1);
void addResourceHandlers(ResourceHandlerRegistry var1);
void addCorsMappings(CorsRegistry var1);
void addViewControllers(ViewControllerRegistry var1);
void configureViewResolvers(ViewResolverRegistry var1);
void addArgumentResolvers(List<HandlerMethodArgumentResolver> var1);
void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> var1);
void configureMessageConverters(List<HttpMessageConverter<?>> var1);
void extendMessageConverters(List<HttpMessageConverter<?>> var1);
void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
Validator getValidator();
MessageCodesResolver getMessageCodesResolver();
}
接下来我们着重⼏个⽅法讲解⼀下:
/* 配置 */
void addInterceptors(InterceptorRegistry var1);
/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);
/**
*静态资源处理
**/
void addResourceHandlers(ResourceHandlerRegistry registry);
/* 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/**
* 这⾥配置视图解析器
**/
void configureViewResolvers(ViewResolverRegistry registry);
/* 配置内容裁决的⼀些选项*/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
1、addInterceptors(InterceptorRegistry registry)
此⽅法⽤来专门注册⼀个Interceptor,如HandlerInterceptorAdapter
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**"); }
}
addPathPatterns("/**")对所有请求都拦截,但是排除了/toLogin和/login请求的拦截。
当spring boot版本升级为2.x时,访问静态资源就会被HandlerInterceptor拦截,⽹上有很多处理办法都是如下写法
.excludePathPatterns("/index.html","/","/user/login","/static/**");
可惜本⼈在使⽤时⼀直不起作⽤,查看请求的路径⾥并没有/static/如图:
于是我改成了"/js/**","/css/**","/images/**"这样页⾯内容就可以正常访问了,我的项⽬结构如下:
2. 页⾯跳转addViewControllers
以前写SpringMVC的时候,如果需要访问⼀个页⾯,必须要写Controller类,然后再写⼀个⽅法跳转到页⾯,感觉好⿇烦,其实重写WebMvcConfigurer中的addViewControllers⽅法即可达到效果了
/**
* 以前要访问⼀个页⾯需要先创建个Controller控制类,再写⽅法跳转到页⾯
* 在这⾥配置后就不需要那么⿇烦了,直接访问localhost:8080/toLogin就跳转到login.jsp页⾯了
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/toLogin").setViewName("login");
}
值的指出的是,在这⾥重写addViewControllers⽅法,并不会覆盖WebMvcAutoConfiguration中的addViewControllers(在此⽅法中,Spring Boot将“/”映射⾄index.html),这也就意味着我们⾃⼰的配置和Spring Boot的⾃动配置同时有效,这也是我们推荐添加⾃⼰的MVC配置的⽅式。
3. ⾃定义资源映射addResourceHandlers
⽐如,我们想⾃定义静态资源映射⽬录的话,只需重写addResourceHandlers⽅法即可。
注:如果继承WebMvcConfigurationSupport类实现配置时必须要重写该⽅法,具体见其它⽂章
@Configuration
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {
/**
* 配置静态访问资源
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/my/**").addResourceLocations("classpath:/my/");
}
}
如果你想指定外部的⽬录也很简单,直接addResourceLocations指定即可,代码如下:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/my/**").addResourceLocations("file:E:/my/");
}
addResourceLocations指的是⽂件放置的⽬录,addResoureHandler指的是对外暴露的访问路径
4. configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
⽤法:
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}
此时会注册⼀个默认的Handler:DefaultServletHttpRequestHandler,这个Handler也是⽤来处理静态⽂件的,它会尝试映射/。当DispatcherServelt映射/时(/ 和/ 是有区别的),并且没有到合适的Handler来处理请求时,就会交给DefaultServletHttpRequestHandler 来处理。注意:这⾥的静态资源是放置在web根⽬录下,⽽⾮WEB-INF 下。
可能这⾥的描述有点不好懂(我⾃⼰也这么觉得),所以简单举个例⼦,例如:在webroot⽬录下有⼀个图⽚:1.png 我们知道Servelt规范中web根⽬录(webroot)下的⽂件可以直接访问的,但是由于DispatcherServlet配置了映射路径是:/ ,它⼏乎把所有的请求都拦截了,从⽽导致1.png 访问不到,这时注册⼀个DefaultServletHttpRequestHandler 就可以解决这个问题。其实可以理解为DispatcherServlet破坏了Servlet的⼀个特性(根⽬录下的⽂件可以直接访问),DefaultServletHttpRequestHandler是帮助回归这个特性的。
5、configureViewResolvers(ViewResolverRegistry registry)
从⽅法名称我们就能看出这个⽅法是⽤来配置视图解析器的,该⽅法的参数ViewResolverRegistry 是⼀个注册器,⽤来注册你想⾃定义的视图解析器等。ViewResolverRegistry 常⽤的⼏个⽅法:
1).enableContentNegotiation()
/** 启⽤内容裁决视图解析器*/
public void defaultViews) {
initContentNegotiatingViewResolver(defaultViews);spring mvc和boot区别
}
该⽅法会创建⼀个内容裁决解析器ContentNegotiatingViewResolver ,该解析器不进⾏具体视图的解析,⽽是管理你注册的所有视图解析器,所有的视图会先经过它进⾏解析,然后由它来决定具体使⽤哪个解析器进⾏解析。具体的映射规则是根据请求的media types来决定的。
2). UrlBasedViewResolverRegistration()
public UrlBasedViewResolverRegistration jsp(String prefix, String suffix) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(prefix);
resolver.setSuffix(suffix);
this.viewResolvers.add(resolver);
return new UrlBasedViewResolverRegistration(resolver);
}
该⽅法会注册⼀个内部资源视图解析器InternalResourceViewResolver 显然访问的所有jsp都是它进⾏解析的。该⽅法参数⽤来指定路径的前缀和⽂件后缀,如:
registry.jsp("/WEB-INF/jsp/", ".jsp");
对于以上配置,假如返回的视图名称是example,它会返回/WEB-INF/jsp/example.jsp给前端,不到则报404。
3). beanName()
public void beanName() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
this.viewResolvers.add(resolver);
}
该⽅法会注册⼀个BeanNameViewResolver 视图解析器,这个解析器是⼲嘛的呢?它主要是将视图名称解析成对应的bean。什么意思呢?假如返回的视图名称是example,它会到spring容器中有没有⼀个叫example的bean,并且这个bean是View.class类型的?如果有,返回这个bean。
4). viewResolver()
public void viewResolver(ViewResolver viewResolver) {
if (viewResolver instanceof ContentNegotiatingViewResolver) {
throw new BeanInitializationException(
"addViewResolver cannot be used to configure a ContentNegotiatingViewResolver. Please use the method enableContentNegotiation instead."); }
this.viewResolvers.add(viewResolver);
}
这个⽅法想必看名字就知道了,它就是⽤来注册各种各样的视图解析器的,包括⾃⼰定义的。
6. configureContentNegotiation(ContentNegotiationConfigurer configurer)
上⾯我们讲了configureViewResolvers ⽅法,假如在该⽅法中我们启⽤了内容裁决解析器,那么
configureContentNegotiation(ContentNegotiationConfigurer configurer) 这个⽅法是专门⽤来配置内容裁决的⼀些参数的。这个⽐
较简单,我们直接通过⼀个例⼦看:
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
/* 是否通过请求Url的扩展名来决定media type */
configurer.favorPathExtension(true)
/* 不检查Accept请求头 */
.ignoreAcceptHeader(true)
.parameterName("mediaType")
/* 设置默认的media yype */
.defaultContentType(MediaType.TEXT_HTML)
/* 请求以.html结尾的会被当成MediaType.TEXT_HTML*/
.mediaType("html", MediaType.TEXT_HTML)
/* 请求以.json结尾的会被当成MediaType.APPLICATION_JSON*/
.mediaType("json", MediaType.APPLICATION_JSON);
}
到这⾥我们就可以举个例⼦来进⼀步熟悉下我们上⾯讲的知识了,假如我们MVC的配置如下:
@EnableWebMvc
@Configuration
public class MyWebMvcConfigurerAdapte extends WebMvcConfigurerAdapter {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/jsp/", ".jsp");
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true)
.ignoreAcceptHeader(true)
.parameterName("mediaType")
.defaultContentType(MediaType.TEXT_HTML)
.mediaType("html", MediaType.TEXT_HTML)
.mediaType("json", MediaType.APPLICATION_JSON);
}
}
controller的代码如下:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论