Spring提供的试图解析器大致分为两类
一类是需要ViewResolver,如
解析JSP的InternalResourceViewResolver
解析Velocity的VelocityViewResolver
解析freemarker的FreeMarkerViewResolver
另一类是直接使用View生成试图对象,如
继承AbstractExcelView的子类
继承AbstractPdfView的子类
我们如果想为我们的系统配置多个试图解析器,可以参考使用试图解析器链这个功能
分两种情况,如果第一类和第二类混合使用,可以使用如下的方法
< property name ="order" >< value > 1 </ value ></ property >
</ bean >
<!-- -继承AbstractExcelView或者其他抽象view->
<bean name="listShows" class="com.springinaction.view.ListShowsView">
<bean id="viewResolverTwo" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
</bean>
这样,当一个Controller访问一个逻辑名时,spring mvc会自动先从order小的解析器寻找,如果找不到,再一次增大order进行寻找,这样,就可以使用试图解析器链
但是,如果我们需要两个第一类的解析器共同使用,用上述方法是不行的,因为那三个解析器都继承自UtlBasedViewResovler,这种情况下,如果发现资源不存在的情况,这种机制不会去通知下一个解析器
所以,就会出现,spring mvc总按照order最小的去解析,及时资源不存在(404错误)为了解决这个问
题,我们可以使用org.springframework.web.servlet.view.ResourceBundleViewResolver来解决
JSP页面(用作输入用),路径/jsp
register.jsp
<% @ taglib prefix = " spring " uri = " http://www.springframework.org/tags " %>
<% @ taglib uri = " http://java.sun.com/jsp/jstl/core " prefix = " c " %>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
< html >
< head >
</ head >
< body >
< form action ="<%=request.getContextPath() %>/register.mvc" method ="post" >
name: < input type ="text" name ="name" value ="<c:out value=" ${status.value}" /> "/>(必须输入)
</ br >
sex: < input type ="text" name ="sex" /> (必须输入,且为0或1) br >
< input type ="submit" value ="submit" />
</ form >
</ body >
</ html >
输入结果显示,使用Velocity 路径/velocity
successV.vm
< body >
this is in velocity template </ body >
< table >
< tr >
< td > ${student.name} </ td >
< td > ${student.sex} </ td >
</ tr >
</ talbe >
</ body >
</ html >
控制器:
import model.Student;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
public class RegisterStudentController extends SimpleFormController {
public RegisterStudentController() {
this .setCommandClass(Student. class );
}
protected ModelAndView onSubmit(Object object, BindException arg1) throws Exception {
return new ModelAndView(getSuccessView(), " student " ,stu);
}
}
在classpath建立资源文件views_zh_CN.properties(这是spring的默认名,可以更改,但需要额外配置)
success.class=org.springframework.web.servlet.view.velocity.VelocityView
success.url=/velocity/successV.vm
表示当逻辑名是success的时候,使用这里定义的试图解析器
web.xml
< web-app version ="2.4"
xmlns ="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/train-servlet.xml </ param-value >
</ context-param >
< servlet >
< servlet-name > train </ servlet-name >
< servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
< load-on-startup > 0 </ load-on-startup >
</ servlet >
< servlet-mapping >
< servlet-name > train </ servlet-name >
< url-pattern > *.mvc </ url-pattern >
</ servlet-mapping >
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
< filter >
< filter-name > character </ filter-name >
< filter-class > Action.CharacterFilter </ filter-class >
</ filter >
< filter-mapping >
< filter-name > character </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< welcome-file-list >
< welcome-file > index.jsp </ welcome-file >
</ welcome-file-list >
</ web-app >
spring配置文件:
< property name ="commandClass" >
< value > model.Student </ value >
</ property >
< property name ="formView" > <!-- -输入页面采用jsp解析器->
<value>register</value>
</property>
<property name="successView"> <!---显示页面使用Velocity解析器->
<value>success</value>
</property>
</bean>
<bean id="simpleUrlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/register.mvc">RegisterStudentController</prop>
</props>
</property>
</bean>
<!---jsp解析器->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
</bean>
<!---配置Velocity->
<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath">
<value>/</value>
</property>
</bean>
<!--配置ResourceBundle,使用配置文件为classpath下的views.properties,views_zh_CN.properties等 -->
< bean id ="viewResouceResolver" class ="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
< property name ="basename" value ="views" />
</ bean >
运行页面,可以看到,我们输入的调用的是jsp页面,显示结果调用的是Velocity,如果采用第一种order的方式
spring mvc会找register.jsp和success.jsp或者register.vm或者success.vm,这样总有一步是错误的