0 0

Spring mvc 使用多种viewResolver的问题5

问题大概是这样的:我配置了两个viewResovler:
 <bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
	  	<property name="resourceLoaderPath" value="/WEB-INF/velo/"/>
	  	<property name= "velocityProperties">      
            <props>      
                 <prop key="input.encoding">utf-8</prop>      
                 <prop key="output.encoding">utf-8</prop>          
            </props>      
        </property>               
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
		  <property name="cache" value="false"/>
		  <property name="prefix" value=""/>
		  <property name="suffix" value=".vm"/>
		  <property name="contentType"><value>text/html;charset=UTF-8</value></property>
		  <property name="exposeSpringMacroHelpers" value="true"/>
		  <property name="order"><value>0</value></property>
	</bean>
	 <bean id="JSPviewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		  <property name="cache" value="false"/>
		  <property name="prefix" value="/WEB-INF/jsp/"/>
		  <property name="suffix" value=".jsp"/>
		  <property name="contentType"><value>text/html;charset=UTF-8</value></property>
		  <property name="order"><value>1</value></property>
	</bean>

目的是为了,请求多种视图,viewResovler的order如上图使用
@RequestMapping(value ="/welcome/user")
	public ModelAndView welcome(HttpServletRequest request,HttpServletResponse response,
			ModelMap modelMap) {
		return new ModelAndView("welcome",modelMap);
		//普通转向
	}

第一次http://localhost:8080/Prj/welcome/user 请求/WEB-INF/velo/目录底下的welcome.vm文件可以正常访问
当我把java代码修改成这样
@RequestMapping(value ="/welcome/user")
	public ModelAndView welcome(HttpServletRequest request,HttpServletResponse response,
			ModelMap modelMap) {
		return new ModelAndView("welcome",modelMap);
		//普通转向
	}

并且把jspresovler的order改成0,把velocity的resovler改成1
目的就是为了在/WEB-INF/jsp/目录下找不到welcome.jsp文件,按理说servlet会继续在另外一个resovler里面来查找.vm文件
应该是去找 /WEB-INF/veclo/目录底下寻找 welcome.vm文件,但是
当我请求上面的请求的时候,tomcat提示404错误,后台打印 说找不到welcome.jsp文件
是什么原因?
各位大虾?

补充:当我把两个order都设为0的时候,也是可以找到的
2011年12月01日 16:41

3个答案 按时间排序 按投票排序

0 0

采纳的答案

public boolean checkResource(Locale locale) throws Exception {
		return true;
	}

罪魁祸首 就是spring实现该方法时返回true,这样相当于view总是存在,从而导致其余视图解析器无法得到解析机会。

覆盖该方法,应该就可以了。

public class IcomJstlView extends JstlView {

	public boolean checkResource(Locale locale) throws Exception {
		File file = new File(this.getServletContext().getRealPath("/")+getUrl());
		return file.exists();//判断该jsp页面是否存在
	}
}

2011年12月10日 00:23
0 0

不错

2014年8月14日 10:37
0 0

我没有用过两个视图,所以看了一下源码,看代码:

DispatchServlet.java中 doDispatch最后是调用render方法做视图渲染的:
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 = null;

	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() + "'");
		}
	}
	else {
		// No need to lookup: the ModelAndView object contains the actual View object.
		view = mv.getView();
		if (view == null) {
			throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
					"View object in servlet with name '" + getServletName() + "'");
		}
	}

	// Delegate to the View object for rendering.
	if (logger.isDebugEnabled()) {
		logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
	}
	view.render(mv.getModelInternal(), request, response);
}

mv.isReference() 是说你是不是用名字代替传递一个View实例给ModelAndView对象,你传递的都是名字,所以再看
protected View resolveViewName(String viewName, Map model, Locale locale, HttpServletRequest request)
			throws Exception {

	for (Iterator it = this.viewResolvers.iterator(); it.hasNext();) {
		ViewResolver viewResolver = (ViewResolver) it.next();
		View view = viewResolver.resolveViewName(viewName, locale);
		if (view != null) {
			return view;
		}
	}
	return null;
}

this.viewResolvers 这个就是你配的两个viewResolvers,分别试着去创建View,再看看创建View的代码
public View resolveViewName(String viewName, Locale locale) throws Exception {
	if (!isCache()) {
		logger.warn("View caching is SWITCHED OFF -- DEVELOPMENT SETTING ONLY: This can severely impair performance");
		return createView(viewName, locale);
	}
	else {
		Object cacheKey = getCacheKey(viewName, locale);
		synchronized (this.viewCache) {
			View view = (View) this.viewCache.get(cacheKey);
			if (view == null) {
				// Ask the subclass to create the View object.
				view = createView(viewName, locale);
				this.viewCache.put(cacheKey, view);
				if (logger.isTraceEnabled()) {
					logger.trace("Cached view [" + cacheKey + "]");
				}
			}
			return view;
		}
	}
}
最终落实到 createView,因为你的两个viewResolvers都是实现的 UrlBasedViewResolver,所以看UrlBasedViewResolver这里面的buildView方法就行了
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,所以只查找了jsp就没有查找fm了

Spring并不会去检查你这个文件(welcome.jsp)是否存在,只是最后渲染的时候交给给自处理 VelocityViewResolver交给Velocity处理,
InternalResourceViewResolver交给 servlet request 处理

也可以说UrlBasedViewResolver找出来的View没有被Spring容器管理,所以他不知道有没有

如果想实现你的功能,可以扩展DispatchServlet的resolveViewName方法,例如:
class MyDispatcherServlet extends DispatcherServlet {
	private List viewResolvers;
	
	@Override
	protected View resolveViewName(String viewName, Map model, Locale locale,
			HttpServletRequest request) throws Exception {
		WebApplicationContext context = getWebApplicationContext();
		for (Iterator it = this.viewResolvers.iterator(); it.hasNext();) {
			ViewResolver viewResolver = (ViewResolver) it.next();
			View view = viewResolver.resolveViewName(viewName, locale);
			if (view != null) {
				
				if (view instanceof AbstractUrlBasedView) {
					try {
						Resource resource = context.getResource(((AbstractUrlBasedView) view).getUrl());
						if (resource == null) {
							// log
							continue;
						}
					} catch (Exception e) {
						// log
						continue;
					}
				}
				
				return view;
			}
		}
		return null;
	}
}
当然你要初始化viewResolvers 因为DispatchServlet中该属性为私有的


网上找到的:
如果为DispatcherServlet指定多个ViewResolver的话,不要给予InternalResour- ceViewResolver以及其他UrlBasedViewResolver子类过高的优先级,因为这些ViewResolver即使找不到相应的视图,也不会返回null以给我们轮询下一个ViewResolver的机会,这样,我们所指定的其他ViewResolver实际上就形同虚设。合理的处理方式是,给予ResourceBundleView- Resolver或者XmlViewResolver这种能够通过返回null以表明无法找到相应视图的ViewResolver较高的优先级,而只是将InternalResourceViewResolver(或者其他类似行为的ViewResolver)添加为最低优先级ViewResolver,以作为DispatcherServlet的后备查找对象。

2011年12月08日 16:53

相关推荐

    Spring MVC使用Demo

    这个"Spring MVC使用Demo"提供了实践操作,帮助开发者深入理解Spring MVC的开发环境配置、注解的使用以及工作原理。 首先,Spring MVC的设计模式基于Model-View-Controller(MVC),它将应用程序的业务逻辑、数据和...

    Spring MVC jar包

    - **DAO层**:Spring MVC中的Service层通常调用DAO层完成数据访问,DAO层使用Hibernate进行具体操作。 在`hibernate3.6.8.chm`文件中,可能包含了Hibernate 3.6.8的官方文档,对于深入理解Hibernate的工作原理和...

    Spring MVC 教程快速入门 深入分析

    二、Spring MVC核心类与接口:Spring MVC架构中包含许多核心组件,如DispatcherServlet、HandlerMapping、Controller、ViewResolver等。这些组件协同工作,处理用户的请求并返回相应的响应。 三、Spring MVC核心...

    最全最经典spring-mvc教程

    除此之外,教程可能还会涵盖Spring MVC的RESTful API设计,如何创建JSON响应,以及使用Spring Boot快速构建Spring MVC应用。Spring Boot简化了配置,提供了预配置的依赖,使得开发者能更快地启动项目。 错误处理和...

    Spring.MVC-A.Tutorial-Spring.MVC学习指南 高清可复制版PDF

    总之,“Spring MVC - A Tutorial”这份指南会详细讲解Spring MVC的各个核心组件和使用技巧,包括控制器的创建、模型数据的管理、视图的渲染、以及各种高级特性。通过学习,开发者可以熟练地运用Spring MVC来构建...

    Spring mvc5.0.3 所有jar包

    14. **MessageConverter**: Spring MVC使用MessageConverter处理HTTP请求和响应的转换,支持JSON、XML等多种格式。 15. **模板引擎**: Spring MVC支持多种模板引擎,如FreeMarker、Thymeleaf等,这些引擎可以将模型...

    spring-MVC.zip_Java spring mvc_spring mvc_spring mvc

    4. **View**:视图是用户界面,Spring MVC支持多种视图技术,如JSP、FreeMarker、Thymeleaf等。视图解析器会根据ModelAndView中的信息来决定渲染哪个视图。 5. **ViewModel**:模型视图,是Model和View的组合,它...

    spring MVC .docx

    10. **Conversion and Validation**: Spring MVC提供了数据转换和验证功能,如使用`@RequestParam`、`@PathVariable`注解自动转换参数,以及使用`@Valid`和`BindingResult`进行表单验证。 11. **Tiles or Layouts**...

    精通Spring MVC4

    配置Spring MVC通常涉及web.xml文件中的DispatcherServlet配置,以及Spring配置文件中定义的Controller、ViewResolver和其他组件。Spring Boot简化了这一过程,通过自动配置和@SpringBootApplication注解可以快速...

    Spring mvc 教程

    - **允许其他MVC实现**:Spring MVC 支持多种不同的 MVC 实现,这为开发者提供了更多的选择性。 - **DispatcherServlet**:这是 Spring MVC 的前端控制器,负责接收 HTTP 请求并分发给合适的后端组件处理。 - **...

    Spring MVC 基础实例源码01

    13. **View Technologies**:Spring MVC支持多种视图技术,如JSP、Thymeleaf、FreeMarker等,可以根据项目需求选择。 14. **RESTful API**:Spring MVC通过`@RestController`和`@RequestMapping`可以轻松创建...

    spring MVC配置详解

    在使用 Spring MVC 之前,需要引入相应的 jar 包,包括 Spring 2.5.6 和 Hibernate 3.2.0。Spring 2.5.6 需要引入的 jar 包有 spring.jar、spring-webmvc.jar、commons-logging.jar、cglib-nodep-2.1_3.jar 等。...

    spring mvc mybatis 整合源码,带数据库脚本,带详细注释

    Spring MVC 和 MyBatis 是两个在Java Web 开发中广泛使用的框架。Spring MVC 作为Spring框架的一部分,负责处理HTTP请求并转发到相应的业务逻辑,而MyBatis则是一个轻量级的持久层框架,用于简化数据库操作。整合这...

    Spring MVC 解读——View,ViewResolver.zip

    Spring MVC提供了多种内置的ViewResolver实现,如InternalResourceViewResolver(用于JSP)和FreeMarkerViewResolver(用于FreeMarker)。开发者可以根据项目需求选择合适的视图解析器,也可以自定义实现。 **1. ...

    基本的spring mvc + spring security实现的登录(无数据库)

    在本项目中,我们主要探讨的是如何利用Spring MVC和Spring Security框架构建一个基本的无数据库登录系统。Spring MVC是Spring框架的一部分,用于处理Web应用程序的请求-响应模型,而Spring Security则是一个强大的...

    spring mvc 的入门级资料

    在 Spring MVC 中,核心类和接口是 DispatcherServlet、HandlerMapping、HandlerAdapter、Controller、ViewResolver、HandlerInterceptor、View 等。 DispatcherServlet 是 Spring MVC 的前置控制器,它负责处理...

    spring MVC简单示例

    Spring MVC易于与Spring的其他模块(如Spring Data JPA、Spring Security等)集成,也支持与第三方库(如Hibernate、MyBatis等)配合使用,实现强大的Web应用功能。 这个"spring MVC简单示例"是为了帮助初学者理解...

    Spring mvc整合mybatis例子

    - `spring-mvc.xml`:配置ViewResolver,比如InternalResourceViewResolver,用于解析视图;配置HandlerMapping和HandlerAdapter,处理控制器的映射和调用。 - `mybatis-config.xml`:MyBatis的核心配置,包括数据...

Global site tag (gtag.js) - Google Analytics