spring在解析视图的时候有两个重要的接口:ViewResolver 和 View
ViewResolver 中只有一个方法 resolveViewName ,提供 view name 和 实际 view的映射;View 中两个方法 getContentType 和 render ,解析请求中的参数并把这个请求处理成某一种 View.
说白了,就是ViewResolver 负责怎么去解析, 而View只代表一种 视图层的技术。
对于一个请求,应该返回什么样的视图是 ViewResolver 来决定的,spring3.0提供的 ViewResolver 包括AbstractCachingViewResolver,XmlViewResolver,ResourceBundleViewResolver,UrlBasedViewResolver,InternalResourceViewResolver,VelocityViewResolver/FreeMarkerViewResolver,ContentNegotiatingViewResolver等。从字面意思我们大致就可以猜出起用途。
我们平时使用ResourceBundleViewResolver或者InternalResourceViewResolver来返回JSP页面,他们就是其中的两个 ViewResolver
<!-- 根据客户端的不同的请求决定不同的view进行响应, 如 /demo/find.json /demo/find.xml --> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <!--设置视图解析排序--> <property name="order" value="1" /> <!-- 设置在没有扩展名时,即: "/user/find" 时的默认展现形式 --> <property name="defaultContentType" value="text/html" /> <!-- 是否从扩展名中取mediaType(如xxx.xml,xxx.html),与mediaTypes匹配 --> <property name="favorPathExtension" value="true" /> <!-- 默认值:format,当favorParameter=true,根据parameterName来获取mediaType,与mediaTypes匹配 --> <property name="parameterName" value="mediaType" /> <!-- 是否从请求的url路径中获取 mediaType(如:/xxx/xxx?mediaType=xml),与mediaTypes匹配 --> <property name="favorParameter" value="true" /> <!-- 是否忽略请求头里的Accept Header属性,为了解决不同浏览器中对应不同的accept --> <property name="ignoreAcceptHeader" value="false" /> <property name="mediaTypes"> <map> <entry key="html" value="text/html" /> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> <entry key="txt" value="text/plain" /> <entry key="xls" value="application/vnd.ms-excel" /> </map> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> <bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <property name="marshaller" ref="xStreamMarshaller" /> </bean> </list> </property> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/jsp/" /> <property name="suffix" value=".jsp"></property> </bean> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/> </list> </property> </bean>
1. spring检查setFavorPathExtension(boolean) ,如果这个属性为true(默认为true),检查请求的后缀名,来返回一种 mediaType ,而后缀名和mediaType是通过ContentNegotiatingViewResolver 配置中的mediaTypes指定的。
2.spring检查 setFavorParameter(boolean) 这个属性是否为true(默认为false),而如果你打开这个属性,那么默认的参数名应为 format ,spring通过你传过去的参数决定返回哪种mediaType。
3.如果前两步没有找到合适的mediaType,则使用defaultViews设置的默认值显示。
4.如果前三步都没有找到合适的mediaType,并且 ignoreAcceptHeader 这个属性为false(默认为false),spring则根据请求头里面设置的ContentType来找适合的mediaType。
最后一点别忘了在web.xml中配置
<servlet> <description>spring mvc 分发器</description> <servlet-name>framework</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!-- spring mvc 配置文件 给DispatcherServlet的父类FrameworkServlet属性contextConfigLocation赋值 包含容器启动时所要执行的内容 如果不配置init-param参数,在服务器启动时,会在WEB-INF目录下查找命名规则为<servlet-name>-servlet.xml的文件,对应到这里就是framework-servlet.xml文件 --> <param-name>contextConfigLocation</param-name> <param-value>classpath*:springmvc-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>framework</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>framework</servlet-name> <url-pattern>*.json</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>framework</servlet-name> <url-pattern>*.xml</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>framework</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
如此,前台可以根据demo/find.xml或者demo/find.json获取不同的数据
后台
@RequestMapping(value = "find") public ModelAndView find() { Map<String,Object> map = HashMap<String,Object>(); map.put("flag", "succ"); map.put("message", "请求成功!"); return new ModelAndView("demo/view",map); }
ContentNegotiatingViewResolver的处理流程(左上角入口)
文章评论