springmvc 報無法解析視圖異常

        最近,前端nginx的日誌一直在報一些URL的請求後端響應是500狀態碼,於是緩存其結果,可以看到一直是報一個 javax.servlet.ServletException: Could not resolve view with name 'xxxx'in servlet with name 'Spring MVC Dispatcher Servlet ‘的異常。

        分析這些報這個異常的的URL,規則都是/xxx/{xxx},報錯的URL都是類似於 /xxx/xxx.jpg之類的跟着後綴的,我們的資源內容中也就是這個路由是對應的是沒有這個jpg的資源的,也就是說自然會是404,但是404竟然也報這個異常和500錯誤碼。

        看了springmvc關於這個異常的出處,很明顯的是View爲null,而view是由resolveViewName獲得的。

protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
		// Determine locale for request and apply it to the response.
		Locale locale = this.localeResolver.resolveLocale(request);
		response.setLocale(locale);

		View view;
		if (mv.isReference()) {
			// We need to resolve the view name.
			view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
			if (view == null) {
				throw new ServletException(
						"Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" +
								getServletName() + "'");
			}
		}
......
}
        我們接下來繼續看resolveViewName實現。
        
	protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
			HttpServletRequest request) throws Exception {

		for (ViewResolver viewResolver : this.viewResolvers) {
			View view = viewResolver.resolveViewName(viewName, locale);
			if (view != null) {
				return view;
			}
		}
		return null;
	}
public View resolveViewName(String viewName, Locale locale) throws Exception {
		RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
		Assert.isInstanceOf(ServletRequestAttributes.class, attrs);
		List<MediaType> requestedMediaTypes = getMediaTypes(((ServletRequestAttributes) attrs).getRequest());
		if (requestedMediaTypes != null) {
			List<View> candidateViews = getCandidateViews(viewName, locale, requestedMediaTypes);
			View bestView = getBestView(candidateViews, requestedMediaTypes);
			if (bestView != null) {
				return bestView;
			}
		}
		if (this.useNotAcceptableStatusCode) {
			if (logger.isDebugEnabled()) {
				logger.debug("No acceptable view found; returning 406 (Not Acceptable) status code");
			}
			return NOT_ACCEPTABLE_VIEW;
		}
		else {
			logger.debug("No acceptable view found; returning null");
			return null;
		}
	}
         我們看到了,是requestedMediaTypes爲null引起的view爲空,而requestedMediaTypes 通過getMediaTypes方法生成,看了裏面的代碼,才明白原來是springmvc會去判斷URI的後綴,然後根據後綴去獲取對應的mediatypes。jpg對應的mediatype是jpg/image。

        因此找到原因了,我們的項目中,關於springmvc的viewresolve的配置,沒有關於這個media的,所以去解析視圖的時候無法解析。解決辦法也很簡單,直接加一個默認的viewsolve就OK了。

<!--通用視圖解析器-->
    <bean id="viewResolverCommon" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"/>  
        <property name="suffix" value=".jsp"/><!--可爲空,方便實現自已的依據擴展名來選擇視圖解釋類的邏輯  -->
        <property name="viewClass">
            <value>org.springframework.web.servlet.view.InternalResourceView</value>
        </property>
        <property name="order" value="1"/>
    </bean>


發佈了52 篇原創文章 · 獲贊 15 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章