接口之多种返回数据类型

时间:2024-02-01 14:18:06

近来在做另一个项目接口设计的时候需要考虑这样一个需求,一套接口需兼容两类数据类型(xml和json)。
基于这个项目,原来的接口均为WSDL,遵守的协议为SOAP,它是基于XML的。

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

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

核心代码如下:

@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,核心代码如下:

@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,还可以这么做,核心配置类如下:

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。