文档章节

Spring MVC 5 文档翻译与解析 —— MVC配置解析

无极客
 无极客
发布于 09/18 08:04
字数 2869
阅读 41
收藏 0

MVC配置

MVC Java config和MVC XML 命名空间提供默认的配置来适应大多数的应用 并且有一系列配置API去定制它

对于更高级的定制,configuration API中无效的见 Advanced Java Config and Advanced XML Config

你不需要理解MVC Java config和 MVC 命名空间创建的下层Bean但如果你想知道更多,见 Special Bean Types 和 Web MVC Config.

启用MVC配置

在Java Config中使用@EnableWebMvc注解

@Configuration
@EnableWebMvc
public class WebConfig {
}

在XML中使用mvc:annotation-driven元素

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <mvc:annotation-driven/>
</beans>

上面注册了一系列Spring MVC基础设施Bean,它们也适应classpath中有效的依赖项: 如JSON,XML负荷转换 启用注解驱动的MVC,并且会自动根据classpath中出现的依赖项来配置bean

MVC配置API

在Java Config中实现WebMvcConfigurer借口

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    // 实现配置方法
}

在XML中则检查mvc:annotation-driven/的子元素和属性。 你可以见Spring MVC XML schema 或者使用你IDE的代码完成功能来发现哪些有效的属性和子元素

类型转换

默认地,对Number和Data类型的formatter已经安装好,包含了对@NumberFormat和@DateTimeFormat注解的支持;如果classpath中出现Joda-Time,对Joda-Time全面支持的格式化库也会被安装

在Java config中,注册自定义formatter和converter

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // ...
    }
}


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven conversion-service="conversionService"/>

    <bean id="conversionService"
            class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="org.example.MyConverter"/>
            </set>
        </property>
        <property name="formatters">
            <set>
                <bean class="org.example.MyFormatter"/>
                <bean class="org.example.MyAnnotationFormatterFactory"/>
            </set>
        </property>
        <property name="formatterRegistrars">
            <set>
                <bean class="org.example.MyFormatterRegistrar"/>
            </set>
        </property>
    </bean>

</beans>

见FormatterRegistrar SPI 和 FormattingConversionServiceFactoryBean使用FormatterRegistrars.

Validation

默认地,如果Bean Validation出现在classpath中,比如Hibernate Validator,LocalValidatorFactoryBean将被注册为全局的对控制器方法参数@Valid和Validated的Validator的Validator

在Java Config中,你可以定制全局Validator接口

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public Validator getValidator(); {
        // ...
    }
}

在XML中,同样

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven validator="globalValidator"/>

</beans>


注意你可以注册本地Validator

@Controller
public class MyController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(new FooValidator());
    }

}

如果需要在某处注入LocalValidatorFactoryBean,亲创建一个Bean并用 @Primary标记它,以避免与MVC配置中声名的那个冲突

Interceptors

在Java config中,注册对发过来的请求应用的interceptor

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LocaleChangeInterceptor());
        registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
        registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
    }
}

XML中同样

<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>

内容类型

你可以配置Spring MVC如何从请求zho9ng决定请求的媒体类型,如:Accept头,URL路径扩展名,查询参数等

默认地URL路径扩展名是首先被检测的——依据classpath依赖json,xml,rss,atom注册为已知扩展 然后Accept 头作为第二优先被检查

考虑改变那些默认值更改为仅仅接受Accept头, 如果你必须使用基于URL的内容类型解析,考虑查询参数策略优先于路径扩展名(不确定) 详情见Suffix match and Suffix match and RFD

在java config中定制请求内容类型解析

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.mediaType("json", MediaType.APPLICATION_JSON);
        configurer.mediaType("xml", MediaType.APPLICATION_XML);
    }
}


<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="mediaTypes">
        <value>
            json=application/json
            xml=application/xml
        </value>
    </property>
</bean>


消息转换器

如果你想替换Spring MVC创建的默认转换器 HttpMessageConverter的定制可以通过覆盖在覆盖configureMessageConverters() JavaConfig完成 而 如果你只是想定制它们或者添加附加的转换器到默认的 ,可以覆盖extendMessageConverters()到默认

下面是一个添加带自定义ObjectMapper的Jackson JSON和XML转换器代替默认实现的例子

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //配置一个ObjectMapper
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
                .indentOutput(true)
                .dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
                .modulesToInstall(new ParameterNamesModule());

        //将ObjectMapper作为MessageConverter的初始化参数
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
        converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
    }
}

上例中,Jackson2ObjectMapperBuilder被用来创建一个MappingJackson2HttpMessageConverter and MappingJackson2XmlHttpMessageConverter 公用的配置 自定义日期格式并添加了对参数名访问支持的jackson-module-parameter-names(JDK8 功能)

此构建器使用以下属性定制Jackson的默认属性 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 关闭 MapperFeature.DEFAULT_VIEW_INCLUSION 关闭

如果在classpath中发现下面著名的模块,它也自动注册

jackson-datatype-jdk7: 支持 Java 7 类型如java.nio.file.Path.

jackson-datatype-joda: 支持 Joda-Time 类型.

jackson-datatype-jsr310: 支持 Java 8 Date & Time API 类型.

jackson-datatype-jdk8: 支持其他Java 8 类型,如 Optional.

使用Jackson XML支持启用缩进支持除了jackson-dataformat-xml外还需要woodstox-core-asl依赖。

其他一些Jackson模块也是有效的

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

jackson-datatype-hibernate: 支持 Hibernate 特殊类型和属性 (包括懒加载切面)

同样可以用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"/>


视图控制器

这有一个捷径,定义一个ParameterizableViewController,它被调用时直接转发到一个视图

用在视图生成Response之前没有Java控制器逻辑去中心的静态情况

转发/的请求到名为home的视图

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("home");
    }
}

同样在XML中使用mvc:view-controller元素

<mvc:view-controller path="/" view-name="home"/>

视图解析器

MVC配置简化View resolver的注册

下面是Java Config例子,它配置使用JSP和Jackson作为默认View来渲染JSON的内容导航视图解析器

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.enableContentNegotiation(new MappingJackson2JsonView());
        registry.jsp();
    }
}
<mvc:view-resolvers>
    <mvc:content-negotiation>
        <mvc:default-views>
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
        </mvc:default-views>
    </mvc:content-negotiation>
    <mvc:jsp/>
</mvc:view-resolvers>

注意FreeMarker, Tiles, Groovy Markup 和 script templates也需要配置下层视图技术

MVC命名空间专门的元素,如FreeMarker:

<mvc:view-resolvers>
    <mvc:content-negotiation>
        <mvc:default-views>
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
        </mvc:default-views>
    </mvc:content-negotiation>
    <mvc:freemarker cache="false"/>
</mvc:view-resolvers>

<mvc:freemarker-configurer>
    <mvc:template-loader-path location="/freemarker"/>
</mvc:freemarker-configurer>

在Java Config中简单地添加各自的Configurer Bean

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.enableContentNegotiation(new MappingJackson2JsonView());
        registry.freeMarker().cache(false);
    }

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("/freemarker");
        return configurer;
    }
}

静态资源

这个选择提供一个方便的方案以提供来自基于Resource的位置的静态资源

下面的例子中,给定一个以/resources开头的请求,相对路径用以寻找和提供静态资源,它相对于 web应用root中位于/public下或classpath中位于/static下。 资源被提供了一年的期限以确保浏览器缓存的使用和浏览器发出Http请求的节约 Last-Modified头也被求值 还会计算Last-Modified头,如果存在,则返回304状态代码。

** 浏览器第一次请求某一URL时,服务器返回状态会是200,同时有一个Last-Modified头标记此文件在服务器端最后修改时间。 客户端再次请求此URL时,向服务器传送If-Modified-Since报头,询问该时间后文件是否有被修改过: 如果服务器端的资源没有变化,则自动返回 HTTP 304(Not Changed.)内容为空,这样就节省了传输数据量**

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
            .addResourceLocations("/public", "classpath:/static/")
            .setCachePeriod(31556926);
    }
}
<mvc:resources mapping="/resources/**"
    location="/public, classpath:/static/"
    cache-period="31556926" />

见 HTTP caching support for static resources. 资源Handler也支持ResourceResolvers和ResourceTransformer链。 链可以用来创建优化资源的工具链 VersionResourceResolver可以用于基于从内容作MD5 Hash计算的,一个固定的应用版本,或其他版本化的资源URL

一个ContentVersionStrategy (MD5 hash) 是一个好的选择,有一些值得注意的例外,如 像用作模块加载器的JavaScript资源

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/public/")
                .resourceChain(true)
                .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
    }
}

你可以使用ResourceUrlProvider去重写URL并应用到整条链的resolver和transformer,比如插入版本

MVC Config提供一个ResourceUrlProvider Bean,它可以被注入到其它Bean

您还可以使用针对Thymeleaf,JSP,FreeMarker和其他具有依赖于HttpServletResponse #creditURL的URL标记的ResourceUrlEncodingFilter使重写透明。

WebJar也支持WebJarsResourceResolver并且当org.webjars:webjars-locator出现在classpath时自动注册。 解析器可以重写URL来包含Jar的版本号并匹配发过来的没有版本号的URL,如"/jquery/jquery.min.js"到 "/jquery/1.2.0/jquery.min.js"

<mvc:resources mapping="/resources/**" location="/public/">
    <mvc:resource-chain>
        <mvc:resource-cache/>
        <mvc:resolvers>
            <mvc:version-resolver>
                <mvc:content-version-strategy patterns="/**"/>
            </mvc:version-resolver>
        </mvc:resolvers>
    </mvc:resource-chain>
</mvc:resources>

默认Servlet

这允许你映射DispatcherServlet到/(也就是覆盖容器默认Servlet映射)而 仍然允许静态资源请求通过容器默认Servlet处理

配置一个URL映射为/**并以相对其他URL映射的最低优先级DefaultServletHttpRequestHandler

这个Handler将转发请求到默认Servlet,因此保持在其他URL的HandlerMapping的最后是很重要的 如果你使用 mvc:annotation-driven或者你配置你自己定制的HandlerMapping接口,请确保设置它的 order属性值低于DefaultServletHttpRequestHandler(Integer.MAX_VALUE)

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}
<mvc:default-servlet-handler/>

对覆盖/ Servlet映射的警告:必须通过名称而不是路径来检索默认Servlet的RequestDispatcher

DefaultServletHttpRequestHandler将尝试在启动时使用大多数主要Servlet容器(Tomcat, Jetty, GlassFish, JBoss, Resin, WebLogic, and WebSphere)的已知名列表自动检测容器的默认Servlet

如果使用不同的名称定义配置了默认Servlet或者在默认Servlet名未知的情况下使用了不同的Servlet容器 ,必须显式提供默认的Servlet名,如下:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable("myCustomDefaultServlet");
    }

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

路径匹配

这允许自定义与URL匹配和URL处理相关的选项。 有关各个选项的详细信息,见PathMatchConfigurer API。

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer
            .setUseSuffixPatternMatch(true)
            .setUseTrailingSlashMatch(false)
            .setUseRegisteredSuffixPatternMatch(true)
            .setPathMatcher(antPathMatcher())
            .setUrlPathHelper(urlPathHelper());
    }
    @Bean
    public UrlPathHelper urlPathHelper() {
        //...
    }
    @Bean
    public PathMatcher antPathMatcher() {
        //...
    }

}
<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"/>

高级Java配置

@EnableWebMvc包含DelegatingWebMvcConfiguration,它提供Spring MVC应用的默认Spring配置并发现和委托 WebMvcConfigurer来定制那些配置

对于高级模式,移除@EnableWebMvc 并直接从DelegatingWebMvcConfiguration继承而不 实现WebMvcConfigurer

@Configuration
public class WebConfig extends DelegatingWebMvcConfiguration {
    // ...
}

你可以保持存在WebConfig中的方法但你现在也可以从基类覆盖Bean声明 并且你仍然可以有classpath下的任意多的其他WebMvcConfigurer

高级XML配置

MVC命名空间不具有高级模式,如果你不得不需要定制一个Bean属性,你可以使用 Spring ApplicationContext中的BeanPostProcessor生命周期钩子:

@Component
public class MyPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
        // ...
    }
}

注意MyPostProcessor需要明确地通过 XML或者<component-scan/>发现 声明为一个Bean

© 著作权归作者所有

共有 人打赏支持
无极客
粉丝 0
博文 7
码字总数 25385
作品 0
潮州
私信 提问
第二章:springmvc入门

2.1、Spring Web MVC是什么 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是...

xiejunbo
2014/12/16
0
0
第二章 Spring MVC入门

2.1、Spring Web MVC是什么 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是...

亮liang
2015/03/20
0
0
springmvc学习笔记(1)-框架原理和入门配置

springmvc学习笔记(1)-框架原理和入门配置 标签: springmvc [TOC] 本文主要介绍springmvc的框架原理,并通过一个入门程序展示环境搭建,配置以及部署调试。 springmvc是spring框架的一个模块...

brianway
2016/03/08
271
0
SpringMVC入门demo

为什么要学习SpringMVC呢? Spring框架号称是JavaEE应用的一站式解决方案,Spring本身有提供了一个设计优良的MVC框架,SpringMVC。由于Spring框架拥有极高的市场占有率,因此越来越多的Sprin...

武小猪
06/26
0
0
Spring4.1新特性——Spring MVC增强

1、GroovyWebApplicationContext 在Spring 4.1之前没有提供Web集成的ApplicationContext,在《Spring4新特性——Groovy Bean定义DSL》中我们自己去实现的com.sishuok.spring4.context.suppo...

莱茵河水怪v241Beta
2015/07/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

安卓的切图规范

Android UI 切图命名规范、标注规范及单位描述 很多UI设计师做APP切图都会有两套,一套是Android的,一套是IOS的。IOS我这边暂不作讲解,因为我本人也不是开发IOS。这里整理一下我在Android...

mo311
30分钟前
2
0
深度剖析阿里巴巴对Flink的优化与改进

摘要: 作者 | 阿里巴巴实时计算团队 导读:随着人工智能时代的降临,数据量的爆发,阿里巴巴的商品数据处理就经常需要面对增量和全量两套不同的业务流程问题,所以阿里巴巴就在想:能不能有...

阿里云官方博客
31分钟前
2
0
Dubbo基础介绍

Dubbo是一个常用的分布式服务框架, 它致力于提供高性能、透明化的RPC远程服务方案。 学习Dubbo有助于提高企业级应用的开发效率,以及可通过简单的配置就可以实现负载均衡,提高服务的效率。...

Java搬砖工程师
42分钟前
4
0
VBS 自动登陆

1.关于网页元素属性 IE浏览器打开网页时,有很多元素,比如说一个文本框,一个按键等。每个元素都会有对应的“name”、“ID”,“style”,“class”等属性。 其中的“ID”和“name”属性是我...

宝贝女儿
46分钟前
1
0
GO 文件相关操作

package mainimport("fmt""os""bufio""io""io/ioutil")type ChartCount struct{Chct intSpacect intNumberct intOtherct int}func main() {file,err := os.Open......

汤汤圆圆
48分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部