Spring MVC 三大组件
2011-01-21 15:36:23| 分类: Spring | 标签:spring mvc handlermapping cotroller viewresolver |字号 订阅
通过处理器映射,你可以将Web 请求映射到正确的处理器 Controller 上。当接收到请求时,DispactherServlet 将请求交给 HandlerMapping 处理器映射,让他检查请求并找到一个合适的HandlerExecutionChain,这个HandlerExecutionChain 包含一个能处理该请求的处理器 Controller。然后,DispactherServlet 执行在HandlerExecutionChain 中的处理器 Controller。
Spring 内置了许多处理器的映射策略,如:SimpleUrlHandlerMapping 或者 BeanNameUrlHandlerMapping。
● SimpleUrlHandlerMapping
SimpleUrlHandlerMapping 在应用上下文中可以进行配置,并且有Ant 风格的路径匹配功能。例如我们在applicationContext.xml 中配置一个SimpleUrlHandlerMapping 处理器映射。
<beans>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<props>
<prop key="/**/help.do">helpAction</prop>
<prop key="/ex/view*.do">helpAction</prop>
<prop key="/*/account.do">accountAction</prop>
<prop key="/*/editAccount.do">accountAction</prop<>>
</props>
</bean>
<bean id="helpAction" class="org.springframework.web.servlet.mvc.UrlFielNameViewController"/>
<bean id="accountAction" class="org.springframework.web.servlet.mvc.SimpleFormController">
<property name="formView" value="account"/>
<property name="successView" value="account-created"/>
<property name="commandName" value="Account">
<property name="commandClass" value="samples.Account"/>
</bean>
</beans>
● BeanNameUrlHandlerMapping
BeanNameUrlHandlerMapping 将收到的Http请求映射到bean 的名字上。如:我们用如下方式将包含http://samples.com/editAccount.do的访问请求映射到指定的FormController 上。
<beans>
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean name="/editAccount.do" class="org.springframework.web.servlet.mvc.SimpleFromController">
<property name="formView" value="account"/>
<property name="successView' value="account-created"/>
<property name="commandName" value="Account"/>
<property name="commandClass" value="samples.Account"/>
</bean>
</beans>
在默认情况下,如果没有在上下文中没有找到处理器映射,DispactherServlet 会为你创建一个BeanNameUrlHandlerMapping。
● HandlerInterceptor 拦截器
在处理器映射中通过配置拦截器(包括处理器执行前、执行后、执行后进行拦截)将使功能更强大。一个自定义的处理器映射不仅可以根据请求的URL,还可以根据和请求相关的session状态来选择处理器。处理器中的拦截器必须实现org.springframework.web.servlet包中的HandlerInterceptor接口,这个接口定义了3个方法,一个是在处理器执行前被调用,一个是在处理器执行后被调用,另一个是在整个请求处理完后调用。
<beans>
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlhandlerMapping">
<property name="interceptor">
<list>
<ref bean="officeHoursInterceptor"/>
</list>
</property>
<property name="mappings">
<props>
<prop key="/*/account.do">accountAction</prop>
<prop key="/*/editAction.do">accountAction</prop>
</props>
</property>
</bean>
<bean id="officeHoursInterceptor" class="samples.TimeBasedAccessInterceptor">
<property name="openningTime" value="9">
<property name="closingTime" value="18">
</bean>
</beans>
public class TimeBaseAccessInterceptor 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{ //在处理器执行前被调用
}
}
㈡ Controller 处理器
Spring 提供了许多功能强大的Controller 的实现,可以继承一个合适的Controller来简化代码。
public ModelAndView handlerRequestInternal( HttpServletRequest request,
ModelAndView mav = new ModelAndView(" hello");
mav. addObject(" message"," HelloWorld!");
return mav;
}
}
<bean id="sampleController" class="samples.SampleController">
<property name="cacheSeconds" value="120"/>
</bean>
public ModelAndAction create( HttpServletRequest request, HttpServletResponse response) throws Exception{
return new ModelAndView(" create",model);
}
public ModelAndView retried( HttpServletRequest request, HttpServletResponse response) throws Exception{
return new ModelAndView(" retried",model);
}
public ModelAndView update( HttpServletRequest request, HttpServletResponse response) throws Exception{
return new ModelAndView(" update",model);
}
public ModelAndView delete( HttpServletRequest request, HttpServletResponse response) throws Exception{
return new ModelAndView(" delete",model);
}
}
<property name="paramName" value=" method"/>
<property name="defaultMethodName" value="retried"/>
</bean>
protected ModelAndView onSubmit( HttpServletRequest request, HttpServletResponse response,
Object command, BindException errors) throws Exception{
String methodName = request.getParameter(" mehod");
if(methodName.equals(" create"))
return create(request,response);
if(methodName.equals(" retried"))
return retired(request.response);
if(method.equals(" update"))
return update(request,response);
if(method.equals(" delete"))
return delete(request,response);
return retired(request,response);
}
public ModelAndAction create(HttpServletRequest request,HttpServletResponse response) throws Exception{
return new ModelAndView("create",model);
}
public ModelAndView retried(HttpServletRequest request,HttpServletResponse response) throws Exception{
return new ModelAndView("retried",model);
}
public ModelAndView update(HttpServletRequest request,HttpServletResponse response) throws Exception{
return new ModelAndView("update",model);
}
public ModelAndView delete(HttpServletRequest request,HttpServletResponse response) throws Exception{
return new ModelAndView("delete",model);
}
}
㈢ ViewResolver 视图解析器
Spring 提供了视图解析器供你在浏览器显示模型数据,而不必拘束再特定的视图技术上。Spring 内置了对JSP、Velocity、FreeMarker模板和XSLT视图等的技术。
Spring 中的视图以名字为标识,视图解析器通过名字来解析视图。
当使用JSP作为视图层技术时,就可以使用UrlBaseViewResolver,这个视图解析器就会将视图名解析成URL:
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
当在一个Web 应用中混合使用不同的视图技术时,你可以使用ResourceBundleViewResolver:
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
<property name="defaultParentView" value="parentView"/>
</bean>
使用InternalResourceViewResolver解析JSP视图
<!-- 定义视图 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.InternalResourceView</value>
</property>
<!-- JSP都放在/目录下 -->
<property name="prefix">
<value>/</value>
</property>
<!-- JSP页面的后缀都是.JSP -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>