21.16.5 拦截器
你可以为所有请求或特定URL地址配置并启用HandlerInterceptors或WebRequestInterceptors。
下面是以Java方式来注册拦截器的例子:
@Configuration
@EnableWebMvc
public class WebConfig extendsWebMvcConfigurerAdapter {
@Override
public voidaddInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(newLocaleInterceptor());
registry.addInterceptor(newThemeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
registry.addInterceptor(newSecurityInterceptor()).addPathPatterns("/secure/*");
}
}
在XML中,可使用<mvc:interceptors>元素:
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/admin/**"/>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/secure/*"/>
<bean class="org.example.SecurityInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
21.16.6 Content Negotiation(内容协商)
你可以通过配置来让Spring MVC决定请求所请求的媒体类型。有几个选项可选:检查URL的路径以匹配文件扩展名;检查”Accept”报头;某个特定的查询参数;或者在请求内容为空时,返回默认的内容类型。默认情况下,在请求的URI中的路径扩展名会首先检查,然后再检查”Accept”报头。
如果在类路径下有对应的依赖包时,MVC Java config和MVC namespace会默认注册json,xml,rss,atom。除此以外,路径下的扩展名对应的媒体类型的映射也会被显式地注册,这也会影响到RFD攻击的白名单中的安全扩展名列表。(详见”后缀名匹配与RFD”这一章节)。
下面这个例子展示了在MVC Java config中定制内容协商选项:
@Configuration
@EnableWebMvc
public class WebConfig extendsWebMvcConfigurerAdapter {
@Override
public voidconfigureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.mediaType("json",MediaType.APPLICATION_JSON);
}
}
在namespace(命名空间)中,<mvc:annotation-driven>元素有content-negotiation-manager属性,它会在里面的ContentNegotiationManager(内容协商管理器)中返回包含了媒体类型和扩展名映射的ContentNegotiationManagerFactoryBean。
如果不使用MVC Java config或MVC namespace,你需要创建一个ContentNegotiationManager实体,并使用它来为请求的映射,和RequestMappingHandlerAdapter,和ExceptionHandlerExceptionResolver来配置RequestMappingHanlerMapping。
请注意,ContentNegotiatingViewResolver现在也可以使用ContentNegotiationManager来配置,所以你可以在整个Spring MVC中使用一个共享的ContentNegotiationManager实例。
在某些特殊情况下,可能需要配置多个ContentNegotiationManager实例,这些实例可能会返回自定的ContentNegotiationStrategy实现。比如,你可能用ContentNegotiationManager来配置ExceptionHandlerExceptionResolver,它总是会把已请求的媒体类型解析成”application/json”。或者你可能想注入某个自定的策略,这个策略有一些逻辑判断,它会在请求中没有内容类型时,选择默认的内容类型(比如XML或JSON)。
21.16.7 View Controllers(视图控制器)
你可以定义一个ParameterizableViewController,当调用它时,会马上forward到某个视图。当在Java controller中,在视图生成响应前没有需要处理的逻辑时,可以使用它。
在Java中,当请求是”/”时,forward到一个叫”home”的视图,见下例:
@Configuration
@EnableWebMvc
public class WebConfig extendsWebMvcConfigurerAdapter {
@Override
public voidaddViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
}
或者在XML中使用<mvc:view-controller>元素:
<mvc:view-controller path="/" view-name="home"/>