-
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个答案 按时间排序 按投票排序
-
采纳的答案
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
-
我没有用过两个视图,所以看了一下源码,看代码:
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的开发环境配置、注解的使用以及工作原理。 首先,Spring MVC的设计模式基于Model-View-Controller(MVC),它将应用程序的业务逻辑、数据和...
- **DAO层**:Spring MVC中的Service层通常调用DAO层完成数据访问,DAO层使用Hibernate进行具体操作。 在`hibernate3.6.8.chm`文件中,可能包含了Hibernate 3.6.8的官方文档,对于深入理解Hibernate的工作原理和...
二、Spring MVC核心类与接口:Spring MVC架构中包含许多核心组件,如DispatcherServlet、HandlerMapping、Controller、ViewResolver等。这些组件协同工作,处理用户的请求并返回相应的响应。 三、Spring MVC核心...
除此之外,教程可能还会涵盖Spring MVC的RESTful API设计,如何创建JSON响应,以及使用Spring Boot快速构建Spring MVC应用。Spring Boot简化了配置,提供了预配置的依赖,使得开发者能更快地启动项目。 错误处理和...
总之,“Spring MVC - A Tutorial”这份指南会详细讲解Spring MVC的各个核心组件和使用技巧,包括控制器的创建、模型数据的管理、视图的渲染、以及各种高级特性。通过学习,开发者可以熟练地运用Spring MVC来构建...
14. **MessageConverter**: Spring MVC使用MessageConverter处理HTTP请求和响应的转换,支持JSON、XML等多种格式。 15. **模板引擎**: Spring MVC支持多种模板引擎,如FreeMarker、Thymeleaf等,这些引擎可以将模型...
4. **View**:视图是用户界面,Spring MVC支持多种视图技术,如JSP、FreeMarker、Thymeleaf等。视图解析器会根据ModelAndView中的信息来决定渲染哪个视图。 5. **ViewModel**:模型视图,是Model和View的组合,它...
10. **Conversion and Validation**: Spring MVC提供了数据转换和验证功能,如使用`@RequestParam`、`@PathVariable`注解自动转换参数,以及使用`@Valid`和`BindingResult`进行表单验证。 11. **Tiles or Layouts**...
配置Spring MVC通常涉及web.xml文件中的DispatcherServlet配置,以及Spring配置文件中定义的Controller、ViewResolver和其他组件。Spring Boot简化了这一过程,通过自动配置和@SpringBootApplication注解可以快速...
- **允许其他MVC实现**:Spring MVC 支持多种不同的 MVC 实现,这为开发者提供了更多的选择性。 - **DispatcherServlet**:这是 Spring MVC 的前端控制器,负责接收 HTTP 请求并分发给合适的后端组件处理。 - **...
13. **View Technologies**:Spring MVC支持多种视图技术,如JSP、Thymeleaf、FreeMarker等,可以根据项目需求选择。 14. **RESTful API**:Spring MVC通过`@RestController`和`@RequestMapping`可以轻松创建...
在使用 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 是两个在Java Web 开发中广泛使用的框架。Spring MVC 作为Spring框架的一部分,负责处理HTTP请求并转发到相应的业务逻辑,而MyBatis则是一个轻量级的持久层框架,用于简化数据库操作。整合这...
Spring MVC提供了多种内置的ViewResolver实现,如InternalResourceViewResolver(用于JSP)和FreeMarkerViewResolver(用于FreeMarker)。开发者可以根据项目需求选择合适的视图解析器,也可以自定义实现。 **1. ...
在本项目中,我们主要探讨的是如何利用Spring MVC和Spring Security框架构建一个基本的无数据库登录系统。Spring MVC是Spring框架的一部分,用于处理Web应用程序的请求-响应模型,而Spring Security则是一个强大的...
在 Spring MVC 中,核心类和接口是 DispatcherServlet、HandlerMapping、HandlerAdapter、Controller、ViewResolver、HandlerInterceptor、View 等。 DispatcherServlet 是 Spring MVC 的前置控制器,它负责处理...
Spring MVC易于与Spring的其他模块(如Spring Data JPA、Spring Security等)集成,也支持与第三方库(如Hibernate、MyBatis等)配合使用,实现强大的Web应用功能。 这个"spring MVC简单示例"是为了帮助初学者理解...
- `spring-mvc.xml`:配置ViewResolver,比如InternalResourceViewResolver,用于解析视图;配置HandlerMapping和HandlerAdapter,处理控制器的映射和调用。 - `mybatis-config.xml`:MyBatis的核心配置,包括数据...