SpringMVC的视图解析器有大概以下几类,以下表示了继承关系
AbstractCachingViewResolver
|----------UrlBasedViewResolver
|----------InternalResourceViewResolver
|----------XmlViewResolver
|---------ResourceBundleViewResolver
在使用过程中遇到一个问题就是打算将jsp分成两类一类是mange管理类的,还有一个就是普通的,所以打算将之分别放在
/WEB-INF/manage下和/WEB-INF/view下
于是自然就要配置两个解析器,如下
<bean id="jspViewResolver1" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="1"></property> <property name="prefix" value="/WEB-INF/manage/"></property> <property name="suffix" value=".jsp"></property> </bean><bean id="jspViewResolver2" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2"></property> <property name="prefix" value="/WEB-INF/view/"></property> <property name="suffix" value=".jsp"></property> </bean>就是这样,order也设置好了(较小的具有较高的优先级),讲道理应该是按照链式查找调用的,但是在访问的时候,/mange下的都能访问到,但是/view下的jsp文件都是404错误
查询了大量的资料,发现问题出现在UrlBasedViewResolver类身上,查阅源码后发现问题在下面:
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(getViewClass());
view.setUrl(getPrefix() + viewName + getSuffix());
String contentType = getContentType();
if (contentType != null) {
view.setContentType(contentType);
}
view.setRequestContextAttribute(getRequestContextAttribute());
view.setAttributesMap(getAttributesMap());
return view;
}
并没有看到有试图去找(getPrefix() + viewName + getSuffix())对应的文件,所以并不会返回null,所以并不会跳过次ViewResovler查找下一个,所以
在定义多一个 ViewResovler的时候,一定把UrlBasedViewResolver及其子类对应的ViewResovler放在最后(优先级靠后)。
(本打算自己定义一个Resovler继承上面的UrlBasedViewResolver,然后重写上面的方法,但担心自己水平不够会出现什么猫腻)最终项目采用的解决方案是
只选用一个解析器,并把prefix的value设置成value="/WEB-INF/”
在controller中返回的时候带上文件名return “manage/index”.
参考:
spring源码地址