今天来说说内容协商机制。
内容协商机制这个太专业的名称,说下来,头一次听的话,估计是无法理解他其中的含义的。
那么我这里就用大白话说一下吧。
就是客户端向服务端发送一个请求,然后服务端给客户端返回什么格式的数据的,是需要两端进行协商的,既然是协商,那么他们有什么协议或者规则呢?
下面一探究竟:
一般现在服务端返回的数据基本都是json格式的数据,以前返回的是xml,那么现在如果要返回xml格式的数据,springmvc也是提供得有方法的。
@RequestMapping系列注解中produces可以指定返回得格式,(@GetMapping是@RequestMapping得一种变形)
写法:
@GetMapping(value = “xxx”,produces = MediaType.APPLICATION_XML_VALUE)
注意:在返回的实体中指定**@XmlRootElement(name = “xxx”)**,指定xml的根元素。即可
@GetMapping(value = "getUser",produces = MediaType.APPLICATION_XML_VALUE)
public User getUser(){
User user = new User();
user.setName("我是admin用户");
return user;
}
package com.osy.entity;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "user")
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
最后得到的结果就是
<user>
<name>我是admin用户</name>
</user>
但是这只是服务端指定的,客户端不能够决定,如果客户端请求这个路径需要换成json格式的数据,那么是做不到的,所以就有了内容协商机制,也就是可以相互协商,客户端需要什么杨的格式,给个参数说明,服务端就可以返回客户端需要的数据了。
在springmvc中,我们需要需要达到内容协商机制,那么就需要覆盖WebMvcConfigurer中的configureContentNegotiation方法,(注释里讲得很详细)
package com.osy.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfiguration {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// 是否通过请求参数来决定返回数据,默认为false
configurer.favorParameter(true)
.ignoreAcceptHeader(true) // 不检查Accept请求头
.parameterName("zyMediaType")// 参数名称,就是通过什么样的参数来获取返回值
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("json",MediaType.APPLICATION_JSON)
.mediaType("xml",MediaType.APPLICATION_XML);
// mediaType此方法是从请求参数扩展名(也就是最后一个.后面的值),
// 然后绑定在parameterName上面,比如/admin/getUser.xml 等同于/admin/getUser?zyMediaType=xml
// 如果不需要这种后缀的,那么就是全部通过参数的方式传递到后台
}
};
}
}
然后我们启动项目测试一下吧:
随意创建一个控制器:(注意,返回的实体中,在类上面必须打上@XmlRootElement注解,不然在请求xml格式的时候会报错)
@GetMapping(value = "testMediaType")
public User testMediaType(){
User user = new User();
user.setName("testMediaType");
return user;
}
实体还是上面的实体,
然后访问:
1、先通过url扩展名的方式访问
http://localhost:8080/admin/testMediaType.json
{"name":"testMediaType"}
http://localhost:8080/admin/testMediaType.xml
<user>
<name>testMediaType</name>
</user>
证明后缀是可以的,然后通过参数来测试一下:(注意参数名是你自己定义的,不一定都是我这个)
http://localhost:8080/admin/testMediaType?zyMediaType=json
http://localhost:8080/admin/testMediaType?zyMediaType=xml
两个地址访问和上面的结果是一样的,这里就不贴出结果了。
虽然xml格式的数据现在很少用了,但是有些特殊的场景还是需要的,get这么一个技能,就可以写一个接口符合两种场景了,就无需为某一种格式的数据单独的写接口了。