Spring4.x官方参考文档中文版——第21章 Web MVC框架(35)

来源:互联网 发布:java 分布式框架 编辑:程序博客网 时间:2024/05/21 15:49

21.16.10 回到默认的Servlet来提供资源

        这样的配置可以把DispatcherServlet对象映射到”/”(这样就覆盖了web容器的默认Servlet的映射),同时,静态资源的请求依然可以被容器的默认Servlet所处理。它会配置一个带有”/**”的URL映射的DefaultServletHttpRequestHandler,对于其他的URL映射来说,其具有最低优先级。

        这个handler会forward所有请求到默认Servlet。因此,将它放置于其他URL HandlerMappings的最后是很重要的。如果你使用<mvc:annotation_driven>或者你设置了自定的HandlerMapping实例,确认设置了低于DefaultServletHttpRequestHandler的order属性值(Integer.MAX_VALUE)。

        为了启用这个特性,可以使用如下设置:

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter{     @Override    public voidconfigureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {       configurer.enable();   } }

        或者在XML中如下配置:

 

<mvc:default-servlet-handler/>

        请注意,覆盖了”/”的Servlet映射后,默认Servlet的RequestDispatcher就必须根据名字而不是路径来进行检索。DefaultServletHttpRequestHandler会会使用主流Servlet容器的名字(Tomcat,Jetty,GlassFish,JBoss,Resin,WebLogic,WebSphere)在启动时自动检测容器的默认Servlet。如果默认Servlet被配置成不同的名字,或者使用了某个不知名的非主流容器,那就必须显式地指定默认Servlet的名字了,如下例:

 

@Configuration@EnableWebMvcpublic class WebConfig extendsWebMvcConfigurerAdapter {     @Override    public voidconfigureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {       configurer.enable("myCustomDefaultServlet");   } }

        或者在XML中,这样配置:

 

<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>

21.16.11 路径匹配

        这个配置可以自定义关于URL映射和路径匹配的很多选项。关于某些独立选项的配置详情,请参阅PathMatchConfigurer API

        下方是用Java config配置的例子:

 

@Configuration@EnableWebMvcpublic class WebConfig extendsWebMvcConfigurerAdapter {     @Override    public voidconfigurePathMatch(PathMatchConfigurer configurer) {       configurer           .setUseSuffixPatternMatch(true)           .setUseTrailingSlashMatch(false)           .setUseRegisteredSuffixPatternMatch(true)           .setPathMatcher(antPathMatcher())           .setUrlPathHelper(urlPathHelper());   }     @Bean    public UrlPathHelperurlPathHelper() {       //...   }     @Bean    public PathMatcherantPathMatcher() {       //...   } }

        使用XML配置时,使用<mvc:path-matching>元素:

 

<mvc:annotation-driven>    <mvc:path-matching       suffix-pattern="true"       trailing-slash="false"       registered-suffixes-only="true"       path-helper="pathHelper"       path-matcher="pathMatcher"/></mvc:annotation-driven> <bean id="pathHelper" class="org.example.app.MyPathHelper"/><bean id="pathMatcher" class="org.example.app.MyPathMatcher"/>

21.16.12 MessageConverters(消息转换器)

        如果你想要替换Spring MVC创建的默认转换器时,可以在Java config方式中,通过覆写configureMessageCoonverters()方法来定制HttpMessageConverter。或者,当你想要自定义转换器或添加额外的转换器到默认的转换器上时,可以覆写extendMessageConverters()来实现。

        下面的例子展示了使用一个定制的ObjectMapper而不是默认的转换器来添加jackson JSON和XML的转换器:

 

@Configuration@EnableWebMvcpublic class WebConfiguration extendsWebMvcConfigurerAdapter {     @Override    public voidconfigureMessageConverters(List<HttpMessageConverter<?>>converters) {       Jackson2ObjectMapperBuilder builder = newJackson2ObjectMapperBuilder()                .indentOutput(true)                .dateFormat(new SimpleDateFormat("yyyy-MM-dd"))                .modulesToInstall(newParameterNamesModule());       converters.add(newMappingJackson2HttpMessageConverter(builder.build()));       converters.add(newMappingJackson2XmlHttpMessageConverter(builder.xml().build()));   } }

        在此例中,Jackson2ObjectMapperBuilder被用来为MappingJackson2HttpMessageConverter和MappingJackson2XmlHttpMessageConverter创建通用的配置,包括了一个自定义的日期格式并注册了jackson-module-parameter-names,它可以用来访问参数名(Java 8的新特性)。

   

    请注意:

        为了支持Jackson XML的缩进,除了jackson-dataformat-xml以外,还需要woodstox-core-asl的支持。

 

        关于Jackson的其他的比较有趣模组也是可用的:

1.  jackson-datatype-money:支持javax.money类型(非官方模组)

2.  Jackson-datatype-hibernate:支持Hibernate特定的类型和属性(包括了lazy-loading方面的支持)

 

        同样的,也可以在XML中进行配置:

 

<mvc:annotation-driven>    <mvc:message-converters>       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">           <property name="objectMapper" ref="objectMapper"/>       </bean>       <bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter">           <property name="objectMapper" ref="xmlMapper"/>       </bean>    </mvc:message-converters></mvc:annotation-driven> <bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"     p:indentOutput="true"     p:simpleDateFormat="yyyy-MM-dd"     p:modulesToInstall="com.fasterxml.jackson.module.paramnames.ParameterNamesModule"/> <bean id="xmlMapper" parent="objectMapper" p:createXmlMapper="true"/>

21.16.13 使用MVC Java Config进行进阶定制

        就如你见到的之前的例子那样,MVC Java config和MVC namespace提供了更高等级的架构,并且不需要了解为你创建的bean的更深层次的知识。这样能让你把注意力集中在你应用的需求上。然而,在某些情况下,你可能需要更细致的控制,或者想了解配置背后的知识。

        为了更细致的控制它,第一步就是了解为你创建的那些bean。在MVC Javaconfig中,你可以看看javadocs和在WebMvcConfigurationSupport类中的@Bean方法。这个类中的配置会通过@EnableWebMvc注解自动地导入。事实上,如果你打开@EnableWebMvc你就能看见@Import声明。

        下一步,是定制在WebMvcConfigurationSupport中的某个bean的属性,或者,让它提供一个你自己的实例。这包括两件事——去除@EnableWebMvc注解来避免导入的操作,并从DelegatingWebMvcConfiguration处继承,它是WebMvcConfiguratioonSupport的子类,见下例:

 

@Configurationpublic class WebConfig extendsDelegatingWebMvcConfiguration {     @Override    public voidaddInterceptors(InterceptorRegistry registry){       // ...   }     @Override    @Bean    publicRequestMappingHandlerAdapter requestMappingHandlerAdapter() {       //创建一个适配器,或者让父类来创建它       //然后,定制这个适配器的某个属性   } }

小提示:

        继承自DelegatingWebMvcConfiguration类,或者单个@EnableWebMvc注解了的类的配置在应用中只能有一个。因为它们注册相同的底层bean。修改这些bean并不会让你不能使用此章节之前展示过的那些高等级架构的配置。WebMvcConfigurerAdapter的子类和WebMvcConfigurer的实现还是会被使用。

 

21.16.14 使用MVC namespace进行进阶定制

        使用命名空间来进行更细致的控制则会更难一些。

        如果你确实要脱离Spring MVC所提供的配置来这么干,可以考虑配置用来根据类型来检测你想配置的bean的BeanPostProcessor类来实现,然后来修改它的属性,如下例:

 

@Componentpublic class MyPostProcessor implements BeanPostProcessor{     public ObjectpostProcessBeforeInitialization(Object bean, String name) throws BeansException {       if (bean instanceof RequestMappingHandlerAdapter) {           // Modify properties of the adapter       }   } }

        请注意,MyPostProcessor需要使用<componentscan/>来把其包含在内,这样才能检测到它,或者你可以在XML的bean声明中显式的声明上它。

1 0
原创粉丝点击