介面之多種返回資料型別

挑戰者V發表於2020-12-19

近來在做另一個專案介面設計的時候需要考慮這樣一個需求,一套介面需相容兩類資料型別(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。

相關文章