接口之多种返回数据类型

近来在做另一个项目接口设计的时候需要考虑这样一个需求,一套接口需兼容两类数据类型(xml和json)。

基于这个项目,原来的接口均为WSDL,遵守的协议为SOAP,它是基于XML的。

于是我想了一些办法做一些扩展,这样的扩展保持WSDL不变的前提下,增加少量代码实现。

由于之前整合Apache CXF用到过,所以很顺利的将其复用过来。

核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@RestController
@RequestMapping("/user")
public class UserApiController {


@PostMapping("/add")
public int add(@RequestParam String email, @RequestParam String username, @RequestParam String password) {

try {
// 接口地址
String address = "http://127.0.0.1:9090/cxf/user?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(UserService.class);
// 创建一个代理接口实现
UserService userService = (UserService) jaxWsProxyFactoryBean.create();

return userService.addUser(email, username, password);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
}

上面是之前整合CXF中的客户端写的例子,我在项目中改为如下,减少了内部通信,直接调用service,核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
@RequestMapping("/user")
public class UserApiController {

@Autowire
private UserService userService;

@PostMapping("/add")
public int add(@RequestParam String email, @RequestParam String username, @RequestParam String password) {

return userService.addUser(email, usern
}
}

这样一来,XML和JSON返回数据类型都兼容,同时请求数据类型既可以是JSON,也可以XML,都能很好的兼容。

当然了,如果只对响应数据类型定义,而不用管请求数据是json还是xml,最简单的办法就是请求头定义(核心是Accept)。

如果是已经写了Controller,原来是JSON数据,现在要求返回XML,还可以这么做,核心配置类如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

@Override
protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true) //是否支持后缀的方式
.parameterName("mediaType")
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML) //当后缀名称为xml的时候返回xml数据
.mediaType("json", MediaType.APPLICATION_JSON);//当后缀名称是json的时候返回json数据
}


}

这样一来针对响应数据类型,你如果要的是xml只需在请求路径加上.xml即可,例如
http://localhost:8080/user/list.xml,
直接能获取xml数据。如果是原来的json数据,路径不变,例如
http://localhost:8080/user/list

http://localhost:8080/user/list.json。

文章目录