欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Web MVC框架学习之配置Spring Web MVC

程序员文章站 2024-04-03 12:45:28
这一篇文章讲的是spring web mvc各部分的配置方法,包括java代码配置和xml文件配置以及mvc命名空间的使用方法。 启用mvc java配置和xml命名空间...

这一篇文章讲的是spring web mvc各部分的配置方法,包括java代码配置和xml文件配置以及mvc命名空间的使用方法。

启用mvc java配置和xml命名空间

默认配置

要启用mvc java配置(@controller等各种注解)和xml命名空间,如果使用的是java配置,在配置类上再添加@enablewebmvc注解即可。

@configuration
@enablewebmvc
public class webappconfig {

}

如果使用xml配置文件的话,添加下面一行即可。

<mvc:annotation-driven/>

不论使用哪种方式,都会在spring中注册一些组件来提供最基本的mvc功能。这些功能在文档中说的很清楚。我简单翻译了一下:

上面的配置会注册一个requestmappinghandlermapping,一个requestmappinghandleradapter和一个exceptionhandlerexceptionresolver来提供注解控制器和注解方法(比如@requestmapping和@exceptionhandler等)处理请求的功能。

还会启用以下功能:

  1. 通过一个conversionservice实例,来进行spring 3 方式的类型转换及数据绑定支持。
  2. @numberformat格式化数字字段的支持
  3. @datetimeformat格式化date、calendar、long、jodatime类型字段的支持。
  4. 在控制器方法上使用@valid验证bean的支持,如果检测到jsr-303 bean验证的实现。
  5. 一组httpmessageconverter,用于在字符串和所需java类型之间进行类型转换,具体的列表参见spring文档 22.16.1. enabling the mvc java config or the mvc xml namespace。

通过这些默认配置,我们即可开始最基本的spring mvc使用。

自定义配置

上面提供了最基本的配置。如果需要自定义某些配置也可以。如果使用java配置的话,让配置类实现webmvcconfigurer接口,更常用的办法是继承webmvcconfigureradapter基类,通过重写基类中的方法即可配置相关功能。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

    //有很多个方法可以重写,来提供自定义功能

}

如果使用xml配置文件,通过ide的自动补全功能查看一下<mvc:annotation-driven/>有哪些子属性和子元素。

类型转换和格式化

默认情况下spring注册了number(包括所有基本数字类型)和java.util.date的类型转换和格式化功能。要提供类型的转换和格式化功能,就需要自己注册相应的类型转换器和格式化器。

如果使用java配置的话,重写addformatters(formatterregistry registry)方法并添加相应功能即可。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public void addformatters(formatterregistry registry) {
    // add formatters and/or converters
  }

}

如果使用xml配置的话,需要注册一个conversionservice,然后添加到<mvc:annotation-driven>节点中。

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

验证功能

spring自己提供了一组接口和类提供了一套验证功能。不过更通用的方法是使用bean validation进行java对象的验证,bean validation的一个实现就是hibernate validator。

默认情况下当@enablewebmvc或<mvc:annotation-driven/>配置之后,如果spring检测到bean validation,就会自动注册一个localvalidatorfactorybean来提供验证功能。如果我们希望手动处理验证过程,可能希望将验证器实例注入到控制器中,这时候就不能使用自动注册的localvalidatorfactorybean了。这时候我们可以选择手动注册一个localvalidatorfactorybeanbean实例,然后注解@primary让自定义localvalidatorfactorybean被优先使用。

还有一种办法就是直接覆盖spring的默认验证器配置。如果使用java配置的话,重写getvalidator()方法即可。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public validator getvalidator() {
    // return "global" validator
  }

}

如果使用xml配置文件,定义一个validator然后添加到<mvc:annotation-driven>中。

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

上面定义的都是全局验证器,我们也可以在某个控制器中定义一个局部验证器,然后和全局验证器结合起来使用。这时候需要使用@initbinder注解方法。

@controller
public class mycontroller {

  @initbinder
  protected void initbinder(webdatabinder binder) {
    binder.addvalidators(new foovalidator());
  }

}

配置好验证器之后。当spring识别到@valid注解的方法参数之后,就会执行验证,将验证结果绑定到bindingresult上,我们可以在方法中访问bindingresult来获取验证结果。

拦截器

我们实现了拦截器之后,就可以将其应用到web程序中。使用java配置的话,重写addinterceptors(interceptorregistry registry)方法,然后在其中添加自己的拦截器即可。如果要配置拦截路径和排除路径也可以在这里配置。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public void addinterceptors(interceptorregistry registry) {
    registry.addinterceptor(new localeinterceptor());
    registry.addinterceptor(new themeinterceptor()).addpathpatterns("/**").excludepathpatterns("/admin/**");
    registry.addinterceptor(new securityinterceptor()).addpathpatterns("/secure/*");
  }

}

使用xml配置文件的话可以使用mvc命名空间,配置也比较简单。

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

视图控制器

这是一种定义parameterizableviewcontroller的简单方式,当该控制器被请求的时候不会执行任何逻辑操作,直接转到相应视图。视图控制器的常见用法是将网站的首页直接和/请求映射。

使用java配置可以这样写,下面的配置将/映射到名为index的视图。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public void addviewcontrollers(viewcontrollerregistry registry) {
    registry.addviewcontroller("/").setviewname("index");
  }

}

使用xml配置也很简单。

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

视图解析器

使用java配置,只需要重写configureviewresolvers(viewresolverregistry registry)方法即可。下面配置了jsp视图。如果需要其它视图解析器可以参见其相应文档,以及viewresolverregistry的javadoc。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public void configureviewresolvers(viewresolverregistry registry) {
    registry.enablecontentnegotiation(new mappingjackson2jsonview());
    registry.jsp()
        .prefix("/web-inf/jsp/")
        .suffix(".jsp")
        .viewclass(jstlview.class);
  }

}

如果使用xml配置文件可以使用mvc命名空间简化配置。除了内置的jsp解析器外,其它视图解析器可能还需要额外的配置,这里不再细述。

<mvc:view-resolvers>
  <mvc:jsp prefix="/web-inf/jsp/"
       suffix=".jsp"
       view-class="org.springframework.web.servlet.view.jstlview"/>
</mvc:view-resolvers>

资源处理

静态资源处理

这里说的主要是静态资源的处理。前面说了很多关于控制器、视图的知识,但是如何映射css、js文件,前面没有说明。配置方法在这里说明。

使用java配置的话,重写addresourcehandlers(resourcehandlerregistry registry)方法,然后添加相应的映射即可。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public void addresourcehandlers(resourcehandlerregistry registry) {
    registry.addresourcehandler("/static/**").addresourcelocations("/resources/static/");
  }

}

使用xml配置文件 也同样简单。

<mvc:resources mapping="/static/**" location="/resources/static/"/>

这样映射之后,假如我们有/resources/static/bootstrap.css文件,那么就可以使用/static/bootstrap.css路径来访问该文件了。同样的在视图文件中也可以如此引用。还可以使用cache-period设置资源的过期时间,单位是秒。如果需要指定多个资源位置,可以使用逗号分隔。

资源的版本控制

有些频繁更新的资源可能需要版本控制,强制让客户端使用最新的资源。spring框架也支持资源的版本控制,我们需要定义资源链来实现这个功能。资源链由一个resourceresolver实例和多个resourcetransformer实例组成。内建的versionresourceresolver能满足我们的大部分需求,它可以定义一些策略来配置版本控制,例如fixedversionstrategy会依据日期、版本号或者其他东西作为版本;contentversionstrategy会计算资源的md5值。

contentversionstrategy策略是一个不错的策略,不过由于它会计算md5,所以开销比较大, 因此在使用这种策略的时候最好打开缓存来提高性能。

如果使用java配置的话,和前面的例子差不多,只不过需要多调用resourcechain(true)等方法并添加相应的版本资源解析器和版本策略。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public void addresourcehandlers(resourcehandlerregistry registry) {
    registry.addresourcehandler("/static/**")
        .addresourcelocations("/resources/static/")
        .resourcechain(true).addresolver(
          new versionresourceresolver().addcontentversionstrategy("/**"));
  }

}

下面是使用xml配置的例子。

<mvc:resources mapping="/static/**" location="/resources/static/">
  <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处理根路径/下的静态资源请求,说的详细点就是假如静态文件是webapp/css/site.css,那么我们可以直接通过/css/site.css来访问这个文件。如果不启用这个功能,那么静态文件就只能映射到其他路径下比如/static。

这个配置项实际上会配置一个defaultservlethttprequesthandler,映射到路径/**,并具有最低的优先级。由于defaultservlethttprequesthandler会将所有请求转发到默认servlet,所以它必须被配置为最后一个处理映射才行。

使用java配置的话,重写configuredefaultservlethandling(...)方法并开启该选项。

@configuration
@enablewebmvc
public class webconfig extends webmvcconfigureradapter {

  @override
  public void configuredefaultservlethandling(defaultservlethandlerconfigurer configurer) {
    configurer.enable();
  }

}

如果使用xml配置的话,添加以下行。

<mvc:default-servlet-handler/>

消息转换

如果我们需要覆盖spring默认的消息转换器,可以重写configuremessageconverters(list<httpmessageconverter<?>> converters)方法,然后向converters参数添加我们自己的消息转换器。如果仅仅希望增加自己的类型转换器,重写extendmessageconverters()方法。

使用xml配置文件的话,可以使用mvc命名空间。

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

高级自定义配置

上面的配置使用spring提供的简化类或者mvc命名空间,帮助我们快速配置功能。有时候可能需要更高级的功能定制,这样就需要自己处理这些底层bean的初始化和属性设置。

java配置自定义

我们先来看一看@enablewebmvc注解的定义。可以看到它还使用了一个@import注解,引用了delegatingwebmvcconfiguration类。当我们注解@enablewebmvc的时候,实际上初始化和配置的底层类就是delegatingwebmvcconfiguration。

@retention(retentionpolicy.runtime)
@target(elementtype.type)
@documented
@import(delegatingwebmvcconfiguration.class)
public @interface enablewebmvc {
}

因此我们如果要自定义mvc的话,第一件事就是移除注解@enablewebmvc。然后继承delegatingwebmvcconfiguration类并实现它的requestmappinghandleradapter()方法。

@configuration
public class webconfig extends delegatingwebmvcconfiguration {

  @override
  @bean
  public requestmappinghandleradapter requestmappinghandleradapter() {
    // 在这里进行高级配置
  }

}

在项目中delegatingwebmvcconfiguration子类和@enablewebmvc注解配置类只能存在一个,因为它们做的事情实际上是一样的。而且这里的配置并不影响spring mvc的其他配置。

自定义mvc命名空间配置

这里的自定义配置更困难,因为spring没有提供相应的配置机制。如果实在需要自定义mvc命名空间配置,可以考虑使用spring提供的beanpostprocessor机制,在检测到bean之后修改它的值。

@component
public class mypostprocessor implements beanpostprocessor {

  public object postprocessbeforeinitialization(object bean, string name) throws beansexception {
    if (bean instanceof requestmappinghandleradapter) {
      // 在这里自定义属性
    }
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。