SpingMVC的内容协商支持三种方式:
- 使用后缀,如
json
、xml
后缀和处理类型的关系可以自己定义 - 前面说的使用
Accept
头 - 在访问时
request
请求的参数,比如每次请求request都会加format=xml
参数,表示要求返回XML格式数据,默认参数名是format
,可以修改。
SpingMVC规定,如果同时开启了上面的部分或全部方式,解析顺序是后缀
、参数
、Accept头
。对我来说,还是比较喜欢用Accept头
,用的时间长,比较适应。
SpingMVC文件中的配置方式如下:
<!-- Make this available across all of Spring MVC -->
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" /> <!-- Total customization - see below for explanation. --> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <property name="favorPathExtension" value="true" /> <property name="favorParameter" value="false" /> <property name="parameterName" value="format" /> <property name="ignoreAcceptHeader" value="false"/> <property name="useJaf" value="false"/> <property name="defaultContentType" value="text/html" /> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> </map> </property> </bean>
favorPathExtension
参数表示是否开启后缀,默认true。(使用形如/account/a.json
、/account/a.xml
的方式)favorParameter
参数表示是否开启request
参数识别,默认false
。(使用形如/account/a?format=json
、/account/?format=xml
的方式)parameterName
参数表示使用参数的名字,默认format
,如果配置为mediaType
,则请求格式变为/account/a?mediaType=json
ignoreAcceptHeader
表示是否关闭accept
头识别,默认false
,即默认开启accept
头识别。defaultContentType
表示服务器默认的MediaType
类型。
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="order" value="0"/> <property name="contentNegotiationManager" ref="contentNegotiationManager"/><!-- 如已配置过管理器,这里可以不配置 --> <property name="viewResolvers"><!-- 这里也可以配置viewResolver --> <list> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </list> </property> <property name="defaultViews"> <list> <!-- 不加配置返回 {"account":{"username":"admin","password":"123456"}} --> <!-- 加配置返回 {"username":"admin","password":"123456"}--> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"> <property name="extractValueFromSingleKeyModel" value="true" /> </bean> <bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <property name="marshaller"> <bean class="org.springframework.oxm.xstream.XStreamMarshaller"/> </property> </bean> </list> </property> </bean>
在Spring4.1
之后提供了视图解析器标签,可以用如下方式
<mvc:view-resolvers>
<mvc:content-negotiation>
<mvc:default-views> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"> <property name="jsonpParameterNames"> <set> <value>jsonp</value> <value>callback</value> </set> </property> <!-- 不加配置返回 {"account":{"username":"admin","password":"123456"}} 加配置返回 {"username":"admin","password":"123456"} --> <property name="extractValueFromSingleKeyModel" value="true" /> </bean> <bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <property name="marshaller"> <bean class="org.springframework.oxm.xstream.XStreamMarshaller"> <!-- 启用annotation --> <property name="autodetectAnnotations" value="true" /> </bean> </property> </bean> </mvc:default-views> </mvc:content-negotiation> <mvc:jsp prefix="/WEB-INF/views/" suffix=".jsp" /> </mvc:view-resolvers>
mvc:content-negotiation
用于定义内容协商的视图解析器,且内部可以定义默认视图;然后我们又定义了mvc:velocity
和mvc:groovy
两个视图解析器;它们会按照顺序进行解析。另外几个视图解析器是:
mvc:freemarker
mvc:bean-name
mvc:jsp
@Controller
public class AccountController { /** * <p>.json结尾返回json</p> * <p>.xml结尾返回xml</p> */ @GetMapping(value="viewResolver") public ModelAndView viewResolver(){ ModelAndView mv = new ModelAndView(); Account account = new Account(WebUtil.getRequest().getParameter("username"), WebUtil.getRequest().getParameter("password")); mv.addObject(account); mv.setViewName("viewResolver"); return mv; } @GetMapping(value="viewResolver2") public String viewResolver2(Model model){ Account account = new Account(WebUtil.getRequest().getParameter("username"), WebUtil.getRequest().getParameter("password")); model.addAttribute(account); return "viewResolver"; } @XStreamAlias("account") public static class Account{ private String username; private String password; public Account(){} public Account(String username, String password) { super(); this.username = username; this.password = password; } //getter setter @Override public String toString() { return "account:{"+username+"|"+password+"}"; } } }