它的做用是在Controller返回的時候進行解析視圖html
@RequestMapping("/advertising") public String advertising(Model model ) { return "ta"; } }
如上 ta就是查找到ta.jsp 而後往WEB-INF目錄進行查找。而WEB-INF是對web來講是安全目錄,是不能直接訪問裏面的資源的java
這個是一個springmvc的視圖解析器,一般是用來配置jsp的web
<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的時候就會出現問題。spring
如:tomcat
我WEB-INF下面有ta.html和tas.jsp安全
<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="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,若是找不到就直接異常了。mvc
若是是html的order比較低,則只會解析html,若是找不到也會直接報異常。app
我想要的效果是優先解析jsp,找不到再解析htnl。jsp
查看源碼UrlBasedViewResolver(InternalResourceViewResolver的父類)ide
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="ta"/>
ta若是jsp解析不到,就做爲html解析
@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; }
補充:
org.springframework.web.servlet.DispatcherServlet
以下視圖解析的時候會for的去找 因此若是不爲空就直接返回
ta若是jsp解析不到,就做爲html解析
補充:
org.springframework.web.servlet.DispatcherServlet
以下視圖解析的時候會for的去找 因此若是不爲空就直接返回