前言:
一、总共有10节,也就是10篇博客来讲述Spring的MVC,几乎涵盖了所有Spring MVC中的内容。
二、我创建的例子是一个球场预订系统,例子我已经测试调试通过,是一个Maven的project,包含一个Parent project:wsheng-spring-base和一个子Module:wsheng-spring-mvc.
三、在Eclipse中直接import maven的project即可,会同时引入上诉两个project的。
四、如果你没有耐心,可以不必往下学习,因为网上有很多例子,但是都是讲的Spring MVC很少的面,而且你可以快速的上手,但如果你想真正了解Spring MVC中的很多细节,就可以慢慢的去看博客(从第一节到第十节),如果有什么问题,欢迎信息告诉我。
五、学习的方法是你可以先将源码导入到eclipse中,然后根据博客上的内容,对照源码,慢慢消化,这是个漫长的过程,但是会帮助你了解很多Spring MVC的细节。
===================================================================================
在Spring3.X @MVC - (六)按照返回的名称解析视图 - Spring MVC中强大的视图解析器的基础上
http://josh-persistence.iteye.com/blog/1884194
进一步的讨论和学习Spring中最为强大的视图解析器: Spring的视图和内容协商机制。
1. 问题:
如果在在控制器中只是返回一个没有扩展名的URL,如welcome,希望设计一个策略:根据具体的请求返回对应的视图:welcome.html或者是welcome.pdf。
2.解决方案:
当web应用接受一个请求时,请求包含一系列的属性,让Sping MVC能够确定返回给请求方的正确的内容和类型。主要的两个属性包括:
1) 请求中的URL的扩展名。
2) HTTP Accept头标。
例如,如果一个url的形式为/welcome.xml的请求,Spring MVC的控制器能够检查扩展名并且将其委派给代表XML视图的一个逻辑视图。
但是如果请求的形式不再是/welcome.xml,而是welcome。这个请求应该委派给一个XML还是一个HTML视图呢?还是一个PDF视图呢?此时通过URL无从知晓。这种情况下的解决方案
A:使用默认的视图:如welcome.html
B:检查请求的HTTP Accept头标来决定哪种视图更加合适。
然而在Spring MVC的控制器中检查HTTP Accept头标可能是个棘手的问题,所以在Sping MVC中专门通过ContentNegotiatingViewResolver解析器支持头标的检查,使视图委派可以根据URL文件扩展名或者HTTP Accept头标值指出。
3. 工作原理:
Sping MVC内容协商解析器基于ContentNegotiationVIewResolver类。下面先介绍下其怎样和其它解析器集成的。
<!-- View resolvers -->
<!-- View exception resolver -->
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop
key="com.wsheng.spring.service.ReservationNotAvailableException">
reservationNotAvailable
</prop>
<prop
key="com.wsheng.spring.web.ReservationWebException">
reservationWebException
</prop>
<!-- Define catch all class or property defaultErrorView -->
<!-- <prop key="java.lang.Exception">error</prop>-->
</props>
</property>
<property name="defaultErrorView" value="error"/>
</bean>
<!-- Views mapped in views.properties (PDF, XLS classes, and others) -->
<bean id="contentNegotiatingResolver"
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order"
value="#{T(org.springframework.core.Ordered).HIGHEST_PRECEDENCE}" />
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="pdf" value="application/pdf"/>
<entry key="xsl" value="application/vnd.ms-excel"/>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
</map>
</property>
</bean>
<bean id="resourceBundleResolver"
class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views" />
<property name="order" value="#{contentNegotiatingResolver.order+1}" />
</bean>
<bean id="secondaryResourceBundleResolver"
class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="secondaryviews" />
<property name="order" value="#{resourceBundleResolver.order+1}" />
</bean>
<!-- Views mapped in JSPs under /WEB-INF/jsp -->
<bean id="internalResourceResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="#{secondaryResourceBundleResolver.order+1}" />
</bean>
1) 你可能发现了,这个程序清单中的解析器声明和前面的看到的不太相同,因为这里面使用Spring的EL表达式SpEL来指定视图解析器的优先顺序。在这个例子中,ContentNegotiatingViewResolver解析器得到了最高的优先权,它的order根据SpEL申明
#{T(org.springframework.core.Ordered).HIGHEST_PRECEDENCE赋值。后续的解析器Bean使用相似的SpEL声明决定order值----#{bean_name.order+1}.这使你可以使用相对的解析器order权重,代替硬编码值。
2) 观察ContentNegotiatingViewResolver解析器的配置,这个配置设置该解析器为所有解析器中的最高优先级别,这种设置其实是有必要的,也就是说,基本上来说,内容协商解析器的优先级应该是最高的。那么为什么内容协商解析器ContentNegotiatinViewResolver要具有最高的优先级呢?原因是该解析器其实不会解析视图,而是将它们委派给其他的视图解析器。看一个例子:
我们假定Sping MVC的控制器接受/reserverationSummary.xml的请求,一旦处理器方法结束,它将控制器发送给名为reservation的逻辑视图。根据前面学的内容可知,当控制器处理结束后,将控制器发送给reservation的逻辑视图后,Spring MVC的解析器开始起作用,因为内容协商处理器的优先级最高,所以开始作用的就是ContentNegotiationViewResolver解析器。
ContentNegotiatingViewResolver解析器首先根据如下原则确定请求的媒体类型
A)检查请求扩展名:根据ContentNegotiationViewResolver bean的MediaType段中指定的默认媒体类型(例如text/html)检查请求路径的扩展名(例如.html, .xml或.pdf)
B)进一步确定请求扩展名: 如果请求路径具有扩展名,但是在ContentNegotiatingViewResolver bean默认的mediaTypes段中找不到,就试图使用属于Java Activation Framework的FileTypeMap确定扩展名的媒体类型。
C)如果没有扩展名:如果请求路径中没有扩展名,使用请求的HTTP Accept头标。
根据上面的A)B) C)的阐述,对于/reservationSummary.xml上的请求,A)中可看出媒体类型为application/xml。但是,对于类似/reservationSummary这样的URL请求,媒体类型在C)之前还没有被确定。其实,HTTP Accept头标中包含类似Accept:text/html或者Accept:application/pdf这样的值,假如请求的URL中不存在扩展名,这些值帮助解析器确定请求者预期的媒体类型。
此时,ContentNegotiatingViewResolver解析器得到一个媒体类型application/xml和reservation的逻辑视图。根据这两个重要的信息,再其他解析器上进行一次循环(根据解析器的顺序),根据检测到的媒体类型(此处为application.xml)确定哪个视图与逻辑名称最为匹配。
这个过程可以允许你拥有多个同名的逻辑视图,每个视图支持一种不同的媒体类型(例如HTML,PDF,XLS),然后由ContentNegotiatingViewResolver来解析最佳匹配。
这就是ContentNegotiatingViewResolver的好处,它会使控制器的设计进一步简化了,因为再也没有必要用硬编码为某个媒体类型创建特定的逻辑视图(例如pdfReservation, xlsReservation, htmlReservation),而代之以单一的视图(reservation),让ContentNegotiatingViewResolver解析器确定最佳匹配。要么匹配reservation.pdf, reservation.html,reservation.xls,reservation.json,reserveration.jsp等。
即可以省掉很多代码:
model.addAttribute("reservations",reservations);
// Check request extension
/**
if(request.getServletPath().endsWith(".pdf")) {
// PDF extension
// Return view pdfSummary. Via resolver the view
// is mapped to the class PdfReservationSummary
// as defined in views.properties
return "pdfSummary";
} else if(request.getServletPath().endsWith(".xls")) {
// Excel extension
// Return view xlsSummary. Via resolver the view
// is mapped to the class ExcelReservationSummary
// as defined in views.properties
return "excelSummary";
} else {
// Any other extension return the file system view reservationSummary
// Via resolver it will be mapped to /WEB-INF/jsp/reservationSummary.jsp
return "reservationSummary";
}*/
return "reservationSummary"; // 只需要这句代码就可。
这个处理过程中,可能的处理过程如下:
A)如果确定媒体类型为application/pdf。如果具有最高优先级的解析器包含有逻辑视图reservation的映射,但是不支持application/pdf类型。那么也就不存在匹配,会继续在剩余的解析器上进心查询匹配。
B)如果确定媒体类型为application/pdf。如果具有最高优先级的解析器包含有逻辑视图reservation的映射,并且这个视图支持application/pdf类型,则匹配该解析器。
C)如果媒体类型确定为text/html,而此时如果有4个名为reservation的逻辑视图,但是如果此时映射到两个具有最高优先级的解析器的视图都不支持text/html。那么就会和剩下的包含reservation视图映射且支持text/html的解析器匹配。
总结:
1) 这个视图搜索过程会在应用中配置的所有解析器上进行。如果你不希望在ContentNegotiatingViewResolver解析器之外进行配置,也可以在ContentNegotiatingViewResolver bean内配置默认视图和解析器。
2)很明显使用视图内容协商处理器(ContentNegotiatingViewResolver)后,可以不用每个逻辑视图(a.html, b.pdf, c.xls)以及为同名的逻辑视图(a: a.html, a.pdf, a.xls, a.json)等找一个最佳的匹配。极大的简化了Spring的视图解析器的配置。
相关推荐
在Spring 3.x的MVC框架中,配置文件起着至关重要的作用,它们定义了Spring MVC应用程序的行为和组件。这篇博客“Spring3.X @MVC - (一)重要的配置文件”可能探讨了如何设置和理解这些配置文件,以及它们如何与...
Spring Web模块和Spring Web MVC模块是Spring框架中的两个关键组成部分,它们在构建Web应用程序时起着至关重要的作用。 Spring Web模块(spring-web-5.2.3.RELEASE.jar)主要负责提供Web相关的功能支持,包括HTTP...
Spring MVC是Spring框架中的模型-视图-控制器(Model-View-Controller)实现,它为构建Web应用程序提供了一种松耦合、可测试和高效的方式。Spring MVC通过DispatcherServlet作为核心控制器,协调其他组件,如处理器...
在Spring MVC框架中,视图和视图解析器是实现MVC模式中“V”(View)部分的关键组件。它们负责将处理完的数据转化为用户可以理解的格式,并展示在浏览器上。视图解析器则是连接控制器与视图的桥梁,它负责根据返回的...
Spring Web MVC提供了一个模型-视图-控制器(MVC)架构,支持处理HTTP请求、渲染视图、处理表单提交等功能。它包括了DispatcherServlet、ModelAndView、ViewController、HandlerMapping、HandlerAdapter等关键组件,...
Spring MVC采用模型-视图-控制器(MVC)设计模式,将应用程序的业务逻辑、数据处理和用户界面分离,提高了代码的可读性和可维护性。它通过DispatcherServlet作为前端控制器,负责请求分发,并通过HandlerMapping将...
Spring MVC 是 Spring 框架的一部分,专门用于构建 Web 应用的模型-视图-控制器架构。`spring-mvc-3.1.xsd` 文件定义了与 MVC 相关的配置元素,如控制器(Controller)、视图解析器(View Resolver)、模型-视图...
首先,Spring Web MVC作为Spring Framework的一部分,主要负责Web应用程序的模型-视图-控制器(MVC)架构实现。它提供了灵活的请求处理机制,支持多种视图技术,并通过依赖注入(DI)和面向切面编程(AOP)提供了...
4. **ViewResolver**:视图解析器根据ModelAndView中的视图名找到具体的视图进行渲染。Spring MVC提供了许多内置的ViewResolver,如InternalResourceViewResolver用于处理JSP视图,VelocityViewResolver则适用于...
它提供了模型-视图-控制器(MVC)架构,使得开发者可以将业务逻辑、数据展示和用户界面分离,从而实现更清晰、可维护的代码结构。在Spring MVC中,`xsd`文件扮演着重要的角色,它们定义了Spring MVC配置的XML Schema...
Spring Web MVC是Spring框架的核心模块之一,专为构建Web应用程序提供模型-视图-控制器(MVC)架构支持。在Spring 5.0.9这个版本中,它延续了Spring对开发者友好、灵活且高性能的设计原则,为开发人员提供了强大的...
本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,现在这一篇补上。下面开始贴代码。 文中用的框架版本:spring 3,hibernate 3,没有的,自己上网下。 先说...
在.NET开发领域,Spring.Web.Mvc3是一个非常重要的框架,它为基于ASP.NET MVC的应用程序提供了强大的依赖注入(DI)和面向方面的编程(AOP)支持。这个“Spring.Web.Mvc3.zip bug修改版”可能是一个修复了原版Spring...
我们可以使用 InternalResourceViewResolver 或其他视图解析器来配置 ViewResolver。 七、总结 Spring MVC 是一个功能强大且灵活的 Web 框架,它提供了许多可配置的组件,以便我们根据需要进行自定义配置。掌握 ...
Spring3.x MVC是Java开发中广泛使用的一个框架,它提供了模型-视图-控制器(MVC)架构,用于构建高效、可维护的Web应用程序。在本教程中,我们将深入探讨Spring3.x MVC的关键特性,通用配置,以及在企业级项目中的...
这个jar文件包含Spring MVC框架相关的所有类。 包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、XSLT相关类。 当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的...
首先,Spring MVC的核心设计理念是模型-视图-控制器(Model-View-Controller)架构模式。在该模式中,模型负责业务逻辑处理,视图负责展示数据,而控制器则作为模型和视图之间的桥梁,接收用户请求并调用相应的服务...
它基于模型-视图-控制器(MVC)设计模式,帮助开发者将业务逻辑、数据处理和用户界面分离开来,使得代码更加清晰和可维护。以下是一些关于Spring 5.1.4和Spring MVC的关键知识点: 1. **依赖注入(Dependency ...
Spring框架是Java开发中不可或缺的一部分,它为构建高效、可重用的Web应用程序提供了强大的支持。在本讨论中,我们将深入探讨两个核心组件——`spring-web.jar`和`spring-webmvc.jar`,它们在Spring MVC框架中扮演着...
2. **Model-View-Controller**:模型-视图-控制器架构,Spring MVC的核心设计模式,将业务逻辑、数据处理和用户界面分离,提高代码的可复用性和可维护性。 3. **HandlerMapping**:处理映射器,负责将请求映射到相应...