SSM之旅(三)--请求的不同输出
restful服务中一个重要的特性就是一种资源可以有多种表现形式,我们可以使用ContentNegotiatingViewResolver解析器来实现。
ContentNegotiatingViewResolver视图解析器是Spring MVC 中常用的一个视图解析器。
这个实现了ViewResolver接口,基于请求文件和Accept 头部信息。ContentNagotiatingViewResolver自己并不解析视图,而是委派给其他的视图处理器。 回过头来,哪些其他的视图解析器
是自动地从应用上下文中挑选出来的,虽然它可以通过viewResolvers属性配置。为了使这个解析器正常工作,序号需要设置成比其他的视图处理器高的优先级。这个视图处理器使用必要的媒体类型为一个请求去选择一个合适的视图。媒体类型通过如下的标准决定:
如果请求路径中包含一个文件扩展名或者将favorPathExtension属性置为true, mediaTypes属性是否匹配媒体类型。
// 是否使用请求文件扩展名作为媒体类型 private boolean favorPathExtension = true; // 是否使用请求参数决定媒体类型 private boolean favorParameter = false; // 媒体类型参数名 private String parameterName = "format"; private boolean useNotAcceptableStatusCode = false; // 是否忽略Accept header private boolean ignoreAcceptHeader = false; private boolean useJaf = jafPresent; // 媒体类型MAP private ConcurrentMap<String, MediaType> mediaTypes = new ConcurrentHashMap<String, MediaType>(); // 默认的视图 private List<View> defaultViews; //默认的媒体类型 private MediaType defaultContentType; // 视图解析器 private List<ViewResolver> viewResolvers;
对应的配置文件如下
ContentNegotiatingViewResolver是根据客户提交的MimeType(如 text/html,application/xml)来跟服务端的一组viewResover的MimeType相比较,如果符合,即返回viewResover的数据.
而 /user/123.xml, ContentNegotiatingViewResolver会首先将 .xml 根据mediaTypes属性将其转换成 application/xml,然后完成前面所说的比较.
<!-- ContentNegotiatingViewResolver配置--> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <!-- contentNegotiation管理器 --> <property name="contentNegotiationManager"> <bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <!-- 1、关闭Accept Header的支持 --> <property name="ignoreAcceptHeader" value="true"/> <!-- 2、关闭参数支持 --> <property name="favorParameter" value="false"></property> <!-- 3、支持后缀匹配支持(上述3种方式) --> <property name="favorPathExtension" value="true"/> <!-- 预设key对应后缀名及参数format的值--> <property name="mediaTypes"> <map> <entry key="htm" value="text/html"/> <entry key="html" value="text/html"/> <entry key="json" value="application/json"/> <entry key="xml" value="application/xml"/> </map> </property> <!-- 在没有扩展名时即: "/param" 时的默认展现形式 --> <property name="defaultContentType" value="text/html"/> </bean> </property> <!-- 使用freeMarker视图解析器 --> <property name="viewResolvers"> <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="cache" value="true"/> <property name="prefix" value=""/> <property name="suffix" value=".ftl"/> <property name="contentType" value="text/html;charset=UTF-8"/> <property name="requestContextAttribute" value="request"/> <property name="exposeSpringMacroHelpers" value="true"/> <property name="exposeRequestAttributes" value="true"/> <property name="exposeSessionAttributes" value="true"/> </bean> </property> <!-- 默认视图 --> <property name="defaultViews"> <list> <!-- for application/json支持--> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"> <property name="prettyPrint" value="true"/> <property name="contentType" value="application/json"/> </bean> <!-- for application/xml支持 --> <bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <property name="marshaller"> <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound" > <list> <!--需要在实体上加上注解@XmlRootElement--> <value>cn.com.youlove.jxt.dal.entity.main.sms.SmsEntity</value> </list> </property> </bean> </property> </bean> </list> </property> </bean> <!-- 上面没匹配到则会使用这个视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="order" value="2" /> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> </bean>
方法resolveViewName中根据方法getMediaTypes获取mediaType(由accept-header、请求参数或后缀名中获取,springmvc每个view的默认contenttype为text/html),根据访问的viewname与mediaType查找候选视图集合candidateViews,再根据方法getBestView获取最优视图并返回。
下一节继续完善ssm框架。使用拦截器做权限拦截。