Spring Web MVC系统学习笔记

来源:互联网 发布:中船重工研究所知乎 编辑:程序博客网 时间:2024/06/06 06:56

转自:http://blog.csdn.net/u011768896/article/details/45000397


参考资料:http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-features

1 Spring Web MVC框架介绍

DispatcherServlet是框架的设计核心,他负责分发请求给处理器、包括可配置的处理映射,视图表现,本地化,时区以及可上传文件式的主题。 
默认的处理器基于注解@Controller和@RequestMapping,提供一个相当大幅度的灵活度处理的方法。 
通过Spring 3.0,@Controller能允许你通过@PathVariable注解创建一个RESTful的web站点和应用程序。 
通过Spring MVC我们可以用任何对象作为控制对象或基于表单的对象,我们不需要实现某框架的特殊接口或继承类。Spring的数据绑定具有很高的灵活性,比如它可以处理类型错误如验证错误一样,使得通过应用程序验证,而不是系统错误。 
Spring MVC的页面处理也非常灵活。Controller不仅是准备一个model的含数据的map的响应,也可以选择一个视图名,并且它可以直接写出response流并且完成请求。 
视图(View)名可通过文件扩展名配置或者接受头内容的类型转让,包括bean的名字,properties问卷或者通过自定义的ViewResolver接口。 
模型(Model)是一个Map接口,它考虑到完全抽象的表现层技术。你可以直接将其表示成JSP,Velocity,Freemarker,或者生成XML,JSON,Atom,和许多其他内容类型。Model的Map可以简单的转换为一个合适的格式,如JSP请求或者Velocity模板。

1.1 Spring Web MVC功能

  • 清晰的分工
  • 强力直观的配置
  • 灵活的,无强制配置,适应性强
  • 可重用的业务代码
  • 自定义的数据绑定和验证
  • 自定义的处理器匹配和页面响应
  • 灵活的模型转换
  • 自定义的时区,本地化以及主题策略
  • 一个简单并强大的JSP标签库,提供了支持功能
  • 对象的生命周期是包括在当前的HTTP request或者 HTTP Session中的

2 The DispatcherServlet

Spring Web MVC框架像许多其他的web MVC框架一样,基于request,并设计成围绕着核心Servlet来分发请求到控制端,控制端提供功能性。 
如下图,DispatcherServlet承担着Front controller的任务。 
这里写图片描述

DispatcherServlet是一个Servlet,他继承自HttpServlet的基类,并且声明自web.xml。我们需要匹配请求来让DispatcherServlet处理,即<url-pattern>,

web.xml :

<web-app>    <servlet>        <servlet-name>example</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>example</servlet-name>        <url-pattern>/example/*</url-pattern>    </servlet-mapping></web-app>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在Servlet3.0+的环境下,也可以通过编码的手段来配置:

编码配置(等价于XML配置):

public class MyWebApplicationInitializer implements WebApplicationInitializer {    @Override    public void onStartup(ServletContext container) {        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet());        registration.setLoadOnStartup(1);        registration.addMapping("/example/*");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

WebApplicationInitializer是Spring MVC提供的基类来初始化Servlet 3的容器。

每一个DispatcherServlet都有一个自己的WebApplicationContext,而这个WebApplicationContext 继承的所有实例都定义在根WebApplicationContext中。 
这里写图片描述

在初始化DispatcherServlet时,Spring MVC寻找一个[servlet-name]-servlet.xml的文件在WEB-INF下,比如example-servlet.xml

他也可以通过配置属性contextConfigLocation来自定义配置文件目录:

<web-app>    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>/WEB-INF/root-context.xml</param-value>    </context-param>    <servlet>        <servlet-name>dispatcher</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value></param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>dispatcher</servlet-name>        <url-pattern>/*</url-pattern>    </servlet-mapping>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener></web-app>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

WebApplicationContext是ApplcationContext基于web应用功能的扩展,它不同于ApplicationContext在可以使用主题,并且可以知道哪个Servlt是被联系的。WebApplicationContext被绑定在ServletContext中,通过RequestContextUtils类中的静态方法,你可以查看WebApplicationContext。

2.1 WebApplicationContext中特殊的Bean类型

Spring的DispatcherServlet使用特殊的Bean去处理请求以及返回页面。我们可以选择单个或多个使用这些bean在WebApplicationContext中。Spring MVC准备了一个默认bean列表,所以当你没有配置时,你并不需要初始化他们。

Bean Type说明HandlerMappingMaps来自请求到处理器和一个预先和延后处理器(即拦截器),基于一些可改变的规则来自HandlerMapping实现。最常用的实现支持注解的控制器HandlerAdapter帮助DispatcherServlet执行一个处理器去匹配不被理会的请求。例如一个注解的controller需要处理大量的注解,因此HandlerAdpater的主要用途是隐藏DisptatcherServlet的细节HandlerExceptionResolver匹配错误至页面ViewResolver处理基于String的View名字至存在的View页面LocaleResolver&LocaleContextResolver用于国际化ThemeResolver提供能用的Web应用主题MulitipartResolver解析上传文件请求FlashMapManager保存并搜索“input”和“output”,能用于传递属性至不同的request,经常用于重定向

2.2 默认的DispatcherServlet配置

所有的特殊Bean都有配置,在org.springframework.web.servlet中的DispatcherServlet.properties。

2.3 DispatcherServlet的处理顺序

  • 获取WebApplicationContext并被绑定为一个控制器以及其他元素可使用的属性。
  • 本地的解析器被绑定到请求。
  • 主题解析器被绑定。
  • 如果指定了复合文件解析器,则请求将检查符合文件
  • 搜索适当的处理器
  • 如果返回了一个model,则提供一个view。

DispatcherServlet可初始化这几个属性:contextClass(自定义的类),contextConfigLocation(配置文件),namespace(默认为[servlet-name]-servlet)。


3 实现Controllers

@Controllerpublic class HelloWorldController {    @RequestMapping("/helloWorld")    public String helloWorld(Model model) {        model.addAttribute("message", "Hello World!");        return "helloWorld";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

@Controller和@RequestMapping这2个注解提供了灵活的方法名即签名配置。 
在以上例子中方法需要接受一个Model类型的形参,并且返回一个String类型的视图名。

3.1 通过@Controller来定义controller

只需要启动扫描注解包就可以使用@Controller来定义包

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:p="http://www.springframework.org/schema/p"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd">    <context:component-scan base-package="org.springframework.samples.petclinic.web"/>    <!-- ... --></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3.2 通过@RequestMapping来匹配请求

@Controller@RequestMapping("/appointments")public class AppointmentsController {    private final AppointmentBook appointmentBook;    @Autowired    public AppointmentsController(AppointmentBook appointmentBook) {        this.appointmentBook = appointmentBook;    }    /* 对于/appointments的HTTP的GET请求调用这个方法 */    @RequestMapping(method = RequestMethod.GET)    public Map<String, Appointment> get() {        return appointmentBook.getAppointmentsForToday();    }    @RequestMapping(value="/{day}", method = RequestMethod.GET)    public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {        return appointmentBook.getAppointmentsForDay(day);    }    /* 对于/appointments/new 的HTTP的GET请求调用这个方法 */    @RequestMapping(value="/new", method = RequestMethod.GET)    public AppointmentForm getNewForm() {        return new AppointmentForm();    }    /* 对于/appointments的HTTP的POST请求调用这个方法 */    @RequestMapping(method = RequestMethod.POST)    public String add(@Valid AppointmentForm appointment, BindingResult result) {        if (result.hasErrors()) {            return "appointments/new";        }        appointmentBook.addAppointment(appointment);        return "redirect:/appointments";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

以上例子使用了很多@RequestMapping注解,第一个在类级别下的@RequestMapping(“/appointments”)说明所有的处理方法都是与appointments相关的。 
get表明只接受get请求。

用@RequestMapping注解来修饰类级别并不是必须的:

@Controllerpublic class ClinicController {    private final Clinic clinic;    @Autowired    public ClinicController(Clinic clinic) {        this.clinic = clinic;    }    @RequestMapping("/")    public void welcomeHandler() {    }    @RequestMapping("/vets")    public ModelMap vetsHandler() {        return new ModelMap(this.clinic.getVets());    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

URL Template Patterns

URL模板可以用在@RequestMapping下的方法。

例如http://www.example.com/users/{userId} 可将fred注入到域中http://www.example.com/users/fred

在Spring MVC中使用@PathVariable注解在形参中,可将其绑定到url模板中的属性。 
详细例子:

@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)public String findOwner(@PathVariable String ownerId, Model model) {    Owner owner = ownerService.findOwner(ownerId);    model.addAttribute("owner", owner);    return "displayOwner";}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

或者:

@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {    // implementation omitted}
  • 1
  • 2
  • 3
  • 4

在类级别使用url模板

@Controller@RequestMapping("/owners/{ownerId}")public class RelativePathUriTemplateController {    @RequestMapping("/pets/{petId}")    public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {        // implementation omitted    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

当使用findPet( )方法后URL:/owners/42/pets/21.

@PathVariable的类型为基本类型。

URL模板也可以匹配正则表达式

3.3 定义@RequestMapping 处理器方法

@RequestMapping处理方法有很高的灵活性。

支持方法参数类型 
- Request和Reponse对象(Servlet API),比如ServletRequest和HttpServletRequest 
- Session object(Servlet API):HttpSession 
- WebRequest或者NativeWebRequest 
- Local,LocaleResolver/LocaleContextResolver 
- TimeZone/ZoneId 
- InputStream/Reader,request内容 
- OutputStream/Writer,response内容 
- HttpMethod,Http请求 
- Principal:包含当前的认证用户 
- @PathVariable:用于URL模板的变量 
- @MatrixVariable:用于URL的键值配对的片段 
- @RequsetParam:用于指定的Servlet request参数 
- @RequestHeader:用于指定的Servlet request的HTTP头 
- @RequestBody:用于指定的HTTP request的body 
- @RequestPart:用于复合数据请求 
- HttpEntity<?>参数用来访问Servlet request HTTP headers和contensts 
- Map/Model,保存了视图所需要的模型数据 
- RedirectAttributes:特定的重定向的属性 
- Errors/BindingResult: 验证结果 
- SessionStatus: 
- UrlComponentsBuilder 
如果使用Errors或者BindingResult,需要如下顺序:

@RequestMapping(method = RequestMethod.POST)public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, Model model) { ... }
  • 1
  • 2

支持的返回类型 
- ModelAndView类型,@ModelAttrivute描述的方法 
- Model类型,@ModelAttribute描述的数据方法 
- Map类型 
- View类型 
- String类型,对应view的名字 
- void,相应自己

通过@RequestParam来绑定请求参数

@Controller@RequestMapping("/pets")@SessionAttributes("pet")public class EditPetForm {    // ...    @RequestMapping(method = RequestMethod.GET)    public String setupForm(@RequestParam("petId") int petId, ModelMap model) {        Pet pet = this.clinic.loadPet(petId);        model.addAttribute("pet", pet);        return "petForm";    }    // ...}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3.4 异步请求处理


4 处理匹配

我们通过@RequestMapping注解来处理匹配,然而,知道所有的HandlerMapping类都是继承自AbstractHandlerMapping可以自定义他们的行为: 
- interceptors:拦截器 
- defaultHandler:默认的处理器 
- order:基于order属性 
- alwaysUseFullPath。 
- urlDecode,默认为true

<beans>    <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">        <property name="interceptors">            <bean class="example.MyInterceptor"/>        </property>    </bean><beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4.1 通过HandlerInterceptor来过滤请求

<beans>    <bean id="handlerMapping"       class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">        <property name="interceptors">            <list>                <ref bean="officeHoursInterceptor"/>            </list>        </property>    </bean>    <bean id="officeHoursInterceptor"            class="samples.TimeBasedAccessInterceptor">        <property name="openingTime" value="9"/>        <property name="closingTime" value="18"/>    </bean><beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
package samples;public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {    private int openingTime;    private int closingTime;    public void setOpeningTime(int openingTime) {        this.openingTime = openingTime;    }    public void setClosingTime(int closingTime) {        this.closingTime = closingTime;    }    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,            Object handler) throws Exception {        Calendar cal = Calendar.getInstance();        int hour = cal.get(HOUR_OF_DAY);        if (openingTime <= hour && hour < closingTime) {            return true;        }        response.sendRedirect("http://host.com/outsideOfficeHours.html");        return false;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

5 处理页面

对于Spring处理视图,ViewResolver和View很重要,ViewResolver提供一个匹配在视图名和视图文件,view接口记录了request的准备已经处理request到视图。

5.1 通过ViewResolver接口处理views

ViewResolver:

ViewResolverDescriptionAbstractCachingViewResolver处理器缓存了一些视图,通常这些视图需要在使用前预处理XMLViewResolver实现ViewResolver能接受配置文件写在XML,默认的配置文件在/WEB-INF/views.xmlResourceBundleViewResolver使用属性文件实现ViewResolver,默认为views.propertiesUrlBasedViewResolver直接将结果映射到URLInternalResourceViewResolverUrlBasedViewResolver的次级类VelocityViewResolver支持VelocityViewContentNegotiationgViewResolver实现ViewResolver接口,通过request的文件名或者accept头来生成视图

URLBasedViewResolver

<bean id="viewResolver"        class="org.springframework.web.servlet.view.UrlBasedViewResolver">    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>    <property name="prefix" value="/WEB-INF/jsp/"/>    <property name="suffix" value=".jsp"/></bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

ResourceBundleViewResolver

<bean id="viewResolver"  class="org.springframework.web.servlet.view.ResourceBundleViewResolver">    <property name="basename" value="views"/>    <property name="defaultParentView" value="parentView"/></bean>
  • 1
  • 2
  • 3
  • 4

5.2 ViewResolver链

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>    <property name="prefix" value="/WEB-INF/jsp/"/>    <property name="suffix" value=".jsp"/></bean><bean id="excelViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">    <property name="order" value="1"/>    <property name="location" value="/WEB-INF/views.xml"/></bean><!-- in views.xml --><beans>    <bean name="report" class="org.springframework.example.ReportExcelView"/></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5.3 重定向views

RedirectView

@RequestMapping(value = "/files/{path}", method = RequestMethod.POST)public String upload(...) {    // ...    return "redirect:files/{path}";}
  • 1
  • 2
  • 3
  • 4
  • 5

The redirect: prefix

redirect:http://myhost.com/some/arbitrary/path

The forward: prefix

5.4 ContentNegotiatingViewResolver

ContentNegotiatingViewResolver 并不自己处理视图,而是委托给其他的视图处理器。 
example:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">    <property name="mediaTypes">        <map>            <entry key="atom" value="application/atom+xml"/>            <entry key="html" value="text/html"/>            <entry key="json" value="application/json"/>        </map>    </property>    <property name="viewResolvers">        <list>            <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">                <property name="prefix" value="/WEB-INF/jsp/"/>                <property name="suffix" value=".jsp"/>            </bean>        </list>    </property>    <property name="defaultViews">        <list>            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />        </list>    </property></bean><bean id="content" class="com.foo.samples.rest.SampleContentAtomView"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

6 使用闪存属性

闪存属性可以提供一个方法给请求去保存。 
Spring MVC有两种主要的方式来支持闪存属性,FlashMap用来保存闪存属性当FlashMapManager用来保存,检索以及管理FlashMap的属性。


7 搭建URL

Spring MVC提供了一个机制去搭建编写URL - UrlComponentsBuilder和UriComponents

扩展并加密URL的例子:

UriComponents uriComponents = UriComponentsBuilder.fromUriString(        "http://example.com/hotels/{hotel}/bookings/{booking}").build();URI uri = uriComponents.expand("42", "21").encode().toUri();
  • 1
  • 2
  • 3
  • 4

UriComponents是不可变的,并且expand( )和encode( )执行将返回一个新的实例。

UriComponents uriComponents = UriComponentsBuilder.newInstance()        .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build()        .expand("42", "21")        .encode();
  • 1
  • 2
  • 3
  • 4

8 本地化

9 使用主题

10 Spring的文件上传

11 处理错误

12 web安全

13 约定优先配置原则

13.1 控制器的匹配

  • WelcomeController 匹配 /welcome*
  • HomeController 匹配 /home*
  • IndexController 匹配 /index *
  • RegisterController 匹配 /register*

  • AdminController匹配/admin/*

  • CatalogController匹配/catalog/*

13.2 模型的ModelMap

  • x.y.User实例生成user
  • x.y.Registration生成registration
  • java.util.HashMap的实例生成hashMap,我们需要明确这个名字,因为hashMap是违背直觉
  • null作为result会跑出一个IllegalArgumentException异常

  • An x.y.User[] array with zero or more x.y.User elements added will have the name userList generated.

  • An x.y.Foo[] array with zero or more x.y.User elements added will have the name fooList generated.
  • A java.util.ArrayList with one or more x.y.User elements added will have the name userList generated.
  • A java.util.HashSet with one or more x.y.Foo elements added will have the name fooList generated.
  • An empty java.util.ArrayList will not be added at all (in effect, the addObject(..) call will essentially be a no-op).

14 ETag支持

15 基于代码的servlet容器配置


16 SpringMVC的配置

16.1 启动MVC的JAVA配置或XML命名空间

基于@Configuration的配置

@Configuration@EnableWebMvcpublic class WebConfig {}
  • 1
  • 2
  • 3
  • 4
  • 5
<?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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

16.2 自定义提供的配置

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter {    @Override    protected void addFormatters(FormatterRegistry registry) {        // Add formatters and/or converters    }    @Override    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {        // Configure the list of HttpMessageConverters to use    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

16.3 拦截器配置

通过java配置:

@Configuration@EnableWebMvcpublic 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/*");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

16.4 内容导航

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter {    @Override    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {        configurer.favorPathExtension(false).favorParameter(true);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" /><bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">    <property name="favorPathExtension" value="false" />    <property name="favorParameter" value="true" />    <property name="mediaTypes" >        <value>            json=application/json            xml=application/xml        </value>    </property></bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

16.5 View Controllers

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter {    @Override    public void addViewControllers(ViewControllerRegistry registry) {        registry.addViewController("/").setViewName("home");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
<mvc:view-controller path="/" view-name="home"/>
  • 1

16.6 View Resolvers

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter {    @Override    public void configureViewResolvers(ViewResolverRegistry registry) {        registry.enableContentNegotiation(new MappingJackson2JsonView());        registry.jsp();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

16.7 静态资源服务

<mvc:resources mapping="/resources/**" location="/public-resources/"/>
  • 1
<mvc:resources mapping="/resources/**" location="/public-resources/">    <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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

16.8 默认的servlet

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

16.9 路径匹配

<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" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

16.10 高级自定义配置

16.11 自定义MVC命名控制


原创粉丝点击