博客引用处(以下内容在原有博客基础上进行补充或更改,谢谢这些大牛的博客指导):
springmvc的InternalResourceViewResolver自我理解
org.springframework.web.servlet.view.InternalResourceViewResolver
他的作用是在Controller返回的时候进行解析视图
prefix 这个表示目录
suffix 这个表示后缀
例:
@RequestMapping("/advertising")
public String advertising(Model model ) {
return "login";
}
}
如上login就是查找到login.jsp 然后往WEB-INF目录进行查找。而WEB-INF是对web来说是安全目录,是不能直接访问里面的资源的
这个是一个springmvc的视图解析器
通常是用来配置jsp的
<bean id="jsp" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="order" value="44" />
<property name="contentType" value="text/html"/>
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
但是我先除了配置jsp还想配置html的时候就会出现问题。
如:
WEB-INF下面有other.html和login.jsp
<mvc:view-controller path="/" view-name="login"/>//注意是以这个为重点
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<!-- 自动扫描(自动注入) -->
<context:component-scan base-package="com.wwzuizz.**.controller"/>
<mvc:resources mapping="/WEB-INF/**" location="/WEB-INF/"/>
<bean id="html" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="order" value="3344" />
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".html"/>
<property name="contentType" value="text/html"></property>
</bean>
<bean id="jsp" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="order" value="44" />
<property name="contentType" value="text/html"/>
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
进行如上配置的时候,根据优先级它会先取jsp,然后在html。可是发现它只是检查一次而已,如如果是jsp的order比较低,则只会解析jsp,如果找不到就直接异常了。
如果是html的order比较低,则只会解析html,如果找不到也会直接报异常。
我想要的效果是优先解析jsp,找不到再解析htnl。
查看源码UrlBasedViewResolver(InternalResourceViewResolver的父类)
protected View loadView(String viewName, Locale locale) throws Exception {
AbstractUrlBasedView view = this.buildView(viewName);
View result = this.applyLifecycleMethods(viewName, view);
return view.checkResource(locale)?result:null;
}
发现这个方法,AbstractUrlBasedView.checkResource()是永远返回true的,也就是如果找不到,也会返回一个result,但是这个result是找不到的。
public boolean checkResource(Locale locale) throws Exception {
return true;
}
为此只需要重写AbstractUrlBasedView这个类
<mvc:view-controller path="/" view-name="ta"/>
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<!-- 自动扫描(自动注入) -->
<context:component-scan base-package="com.wwzuizz.**.controller"/>
<mvc:resources mapping="/WEB-INF/**" location="/WEB-INF/"/>
<bean id="html" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="order" value="3344" />
<property name="viewClass" value="com.wwzuizz.common.DefaultJstlView"/>
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".html"/>
<property name="contentType" value="text/html"></property>
</bean>
<bean id="jsp" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="order" value="44" />
<property name="viewClass" value="com.wwzuizz.common.DefaultJstlView"/>
<property name="contentType" value="text/html"/>
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
com.wwzuizz.common.DefaultJstlView
public class DefaultJstlView extends JstlView {
@Override
public boolean checkResource(Locale locale) throws Exception {
File file = new File(this.getServletContext().getRealPath("/") + getUrl());
return file.exists();//判断该jsp页面是否存在
}
}
这样子如果不存在就传递给下一个InternalResourceViewResolve;其实我很好奇order是在哪里实现的代码,我带入tomcat源码页找不到是哪里的
这样子就可以做到
<mvc:view-controller path="/" view-name="login"/>
ta如果jsp解析不到,就作为html解析
补充:
org.springframework.web.servlet.DispatcherServlet
如下视图解析的时候会for的去找 所以如果不为空就直接返回
@Nullable
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,
Locale locale, HttpServletRequest request) throws Exception {
if (this.viewResolvers != null) {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}