Spring MVC

Spring MVC框架围绕DispatcherServlet这个核心展开,DispatcherServlet是Spring MVC最重要的Servlet,它负责截获请求并将其分派给相应的处理器处理.

Spring MVC 框架包括注解驱动控制器,请求及相应的信息处理, 视图解析,本地化解析,上传文件解析,异常处理,及表单标签绑定等内容

Spring如何将上下文的Spring MVC 组件装配到DispatcherServlet中,查看DispatcherServlet的initStrategies()方法的代码,

(ApplicationContext是Spring的核心,Context我们通常解释为上下文环境,我想用“容器”来表述它更容易理解一些,ApplicationContext则是“应用的容器”了;在Web应用中,我们会用到WebApplicationContext,WebApplicationContext继承自ApplicationContext;WebApplicationContext的初始化方式和BeanFactory.ApplicationContext有所区别,因为WebApplicationContext需要ServletContext实例,也就是说它必须拥有Web容器的前提下才能完成启动的工作.)

initStrategies()方法将在WebApplicationContext初始化后自动执行,此时Spring上下文中的Bean已经初始化完毕,该方法的工作原理是通过反射查找并装配Spring容器中用户显式自定义的组件Bean,找不到,就装配默认的组件实例.

RequestMapping

不但支持标准URL,还支持Ant风格的和带占位符{XXX}的URL

ANT通配符有三种:

通配符 说明
? 匹配任何单字符
* 匹配0或者任意数量的字符
** 匹配0或者更多的目录

例子:

URL路径 说明
/app/*.x 匹配(Matches)所有在app路径下的.x文件
/app/p?ttern 匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern
/**/example 匹配(Matches) /app/example, /app/foo/example, 和 /example
/app/*/dir/file. 匹配(Matches) /app/dir/file.jsp, /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java
/*/.jsp 匹配(Matches)任何的.jsp 文件
Spring MVC的配置

配置视图解析器

1
2
3
4
5
<bean id="viewResolver" 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"></property>
</bean>

请求处理方法签名详解

@RequestParam绑定请求参数值

@CookieValue绑定请求中的Cookie值

@RequestHeader 绑定请求报文头的属性值

使用Servlet API作为入参 如HttpServletRequest request

使用HttpMessageConverter<T>

HttpMessageConverter<T>是Spring的一个重要接口,负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为相应信息.

Spring 为HttpMessageConverter<T>提供了多个实现类,这些类组成了一个功能强大,用途广泛的信息转换家族.Spring中已经默认装配了以下的HttpMessageConverter,StringHttpMessageConverter ByteHttpMessageConverter SourceHttpMessageConverter XmlAwareFormHttpMessageConverter,如果要装配其他的HttpMessageConverter,则应该自行定义一个RequestMappingHandlerAdapter

1
2
3
4
5
6
7
8
9
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
...
</list>
</property>
</bean>

如何使用HttpMessageConvert<T>将请求信息转换并绑定到处理方法的入参,可以使用@RequestBody和@ReponseBody对处理方法进行标注,


<mvc:annotation-driven>会自动注册RequestMappingHandlerMappingRequestMappingHandlerAdapter两个bean

<mvc:default-servlet-handler/>使用默认的Servlet来相应静态文件


数据绑定

数据转换

spring在核心模型中添加了一个通用的类型转换模块,类型转换模块位于org.springframework.core.convert包中,spring希望用这个类型转换体系替换Java标准中的PropertyEditor.

ConversionService是spring类型转换体系的核心接口,位于org.springframework.core.convert包中.也是该包唯一一个接口.

可以利用org.springframework.context.support.ConversionServiceFactoryBean在spring的上下文中定义一个ConversionService. spring将自动识别上下文的ConversionService ,并在Bean属性配置及SpringMVC处理方法入参绑定等场合使用它进行数据转换.

1
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"/>

可以通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器,代码如下:

1
2
3
4
5
6
7
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property>
<list>
<bean class ="com.sysu.MyConverter">
</list>
</property>
</bean>

当实现一个自定义的转换器时,需要实现Converter接口,这个接口仅有一个接口方法,它的接口定义如下:

1
2
3
4
public interface Converter<S, T>
{
T convert(S source);
}//负责将S类型的对象转换为T类型的对象,

在SpringMVC中使用ConversionService例子

将一个请求参数字符串直接转换为User对象,

先定义一个自定义转换器

1
2
3
4
5
6
7
8
9
public class StringToUserConverter implements Converter<String,User>
{
public User convert(String source)
{
User user= new User();
//<将字符串转为对象的代码>
return user;
}
}

编写好转换器后,将其声明在spring上下文中,

1
2
3
4
5
6
7
8
<mvc: annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property names="converters">
<list>
<bean class=com.sysu.converters.StringToUserConverter> //上面那个
</list>
</property>
<bean/>

在装配好StringToUserConverters后,就可以在任何控制器的处理方法中使用这个转换器了.

1
2
3
4
5
@RequestMapping(value="/path")
public String hand(@RequestParam("user") User user)
{
return user;
}

当访问localhost:8080/path?user=tom:1234:tomon时就会自动使用控制器转换了.

视图和视图解析器

SpringMVC借助视图解析器(ViewResolver)得到最终的视图对象(View),这可以是常见的jsp视图,也可能是基于FreeMarker,Velocity 模板技术的视图,还可能是PDF,Execl,XML.JSON等各种形式的视图.

不同的视图实现技术对应不同的View实现类,这些视图实现类都位于org.springframework.web.servlet.view包中,

SpringMVC为逻辑视图名的解析提供了不同的策略,可以在Spring web上下文中配置一种或者多种解析策略,并指定先后顺序,每种解析策略对应一个具体的视图解析器实现类. 所以视图解析器都实现了ViewResolver接口,该接口只有一个方法

1
View resolverViewName(String viewName,Locale locale)

JSP是最常见的视图技术,配置JSP视图解析如下:

1
2
3
4
5
<bean 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"></property>
</bean>

静态资源处理

在web.xml的dispatcherServlet中,设置<urlpattern>/<urlpattern>,所有请求都被SpringMVC的dispatcherServlet截获.

采用<mvc:default-servlet-handler/>

配置上面的语句后,spring会在上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它充当检察员的责任,对进入dispatcherservlet的url进行检查,如果发现是静态资源的请求,就将该请求转由web应用服务器默认的servlet处理.

采用<mvc:resources/>

配置后,springMVC自己处理静态资源,并添加一些有用的附加功能.