Java 当需要两种类型的返回对象时,如何编写RESTAPI调用

Java 当需要两种类型的返回对象时,如何编写RESTAPI调用,java,spring,rest,Java,Spring,Rest,我已经使用Spring编写了一个REST端点 @RequestMapping(value = "/staticdata/userPreference/extUserId/{extUserId}/type/{type}", method = RequestMethod.GET) public ResponseEntity<List<UserPreference>> getData( @PathVariable String extUserId,

我已经使用Spring编写了一个REST端点

@RequestMapping(value = "/staticdata/userPreference/extUserId/{extUserId}/type/{type}", method = RequestMethod.GET)
public ResponseEntity<List<UserPreference>> getData(
        @PathVariable String extUserId,
        @PathVariable String type) {

    List<UserPreference> userPreferences = null;
    userPreferences = staticDataService.getUserPreference(extUserId, type);
    return new ResponseEntity<List<UserPreference>>(userPreferences, HttpStatus.OK);
}

@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleError(HttpServletRequest req, Exception exception) {
    return new ResponseEntity<String>(exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
@RequestMapping(value=“/staticdata/userPreference/extUserId/{extUserId}/type/{type}”,method=RequestMethod.GET)
公共响应获取数据(
@PathVariable字符串extUserId,
@路径变量(字符串类型){
List userPreferences=null;
userPreferences=staticDataService.getUserPreference(extUserId,类型);
返回新的响应属性(userPreferences,HttpStatus.OK);
}
@ExceptionHandler(RuntimeException.class)
公共响应句柄错误(HttpServletRequest请求,异常){
返回新的响应属性(exception.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
}
当getData()方法能够成功获取数据时,它需要返回列表。但是,当出现异常时。消息将被返回。这由handleError()方法处理。此方法返回一个字符串

我的问题是:
使用Spring提供的restTemplate调用这个rest服务应该是什么样子?方法的返回可以是列表,也可以是基于失败的成功的字符串。

您可以尝试
restemplate#exchange
执行请求并以
ResponseEntity
的形式获取响应,然后通过
ResponseEntity\getBody
获取
列表

如果有错误,您可以从
httpstatuscodecoexception.getResponseBodyAsString
获取错误响应

以下是一个例子:

try {
    HttpHeaders headers = new HttpHeaders();
    // add some headers
    HttpEntity<String> request = new HttpEntity<String>(headers);    
    ResponseEntity<List<UserPreference>> response = restTemplate.exchange(
        YOUR_URL, HttpMethod.GET, request, new ParameterizedTypeReference<List<UserPreference>>() {});
    List<UserPreference> userPerference = response.getBody();
} catch (HttpStatusCodeException e) {
    String errorBody = e.getResponseBodyAsString();
}
测试配置:

@SpringBootApplication
public class TestConfig {

}
集成测试包含两个测试用例。一个是测试获取列表响应,另一个是测试从错误响应获取消息体:

@RestController
public class TestController {

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ResponseEntity<List<String>> getData(@RequestParam(value = "error", required = false) String error) {
        if (error != null && error.equals("true")) {
            throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
        } else {
            List<String> list = new ArrayList<>();
            list.add("test");
            return new ResponseEntity<List<String>>(list, HttpStatus.OK);
        }
    }

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleError(HttpServletRequest req, Exception exception) {
        return new ResponseEntity<String>("Exception Message", HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfig.class)
@WebIntegrationTest
public class IntegrationTest {

    @Value("${local.server.port}")
    int port;

    final RestTemplate template = new RestTemplate();

    @Test
    public void testGetListResponse() {
        String url = "http://localhost:" + port + "/test";
        ResponseEntity<List<String>> response = template.exchange(
                url, HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {});
        List<String> list = response.getBody();
        Assert.assertEquals(list.size(), 1);
        Assert.assertEquals(list.get(0), "test");
    }

    @Test
    public void testGetErrorResponse() {
        String url = "http://localhost:" + port + "/test?error=true";
        String errorBody = null;
        try {
            ResponseEntity<List<String>> response = template.exchange(
                    url, HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {
                    });
        } catch (HttpStatusCodeException e) {
            errorBody = e.getResponseBodyAsString();
        }
        Assert.assertEquals(errorBody, "Exception Message");
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes=TestConfig.class)
@网络集成测试
公共类集成测试{
@值(${local.server.port}”)
国际港口;
最终RestTemplate模板=新RestTemplate();
@试验
public void testGetListResponse(){
字符串url=”http://localhost:“+端口+”/测试”;
ResponseEntity response=template.exchange(
url,HttpMethod.GET,null,新的ParameteredTypeReference(){});
List=response.getBody();
Assert.assertEquals(list.size(),1);
Assert.assertEquals(list.get(0),“test”);
}
@试验
public void testGetErrorResponse(){
字符串url=”http://localhost:“+port+”/test?error=true”;
字符串errorBody=null;
试一试{
ResponseEntity response=template.exchange(
url,HttpMethod.GET,null,新参数化类型引用(){
});
}捕获(HttpStatusCodeException){
errorBody=e.getResponseBodyAsString();
}
Assert.assertEquals(errorBody,“异常消息”);
}
}

希望这能有所帮助。

引发的异常是-RestClientException,而不是HttpStatusCodeException。RestClientException没有getResponseBodyAsString。我只需要把一个字符串返回给调用类。您提供的代码,我使用了相同的代码,但是当REST服务器上存在运行时异常时,RestClientException失败。什么是RestClientException?您可以发布堆栈跟踪吗?原因是:org.springframework.web.client.HttpClientErrorException:404在org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)在org.springframework.web.client.restemplate.handleResponse(restemplate.java:641)上找不到在org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)在org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)在org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:503)这是标准的HttpStatus.NOT发现异常。我已调试,以查看异常对象不包含REST服务中引发的RuntimeException详细信息。很抱歉,我已将“内部\u服务器\u错误”更改为“未找到”。但是结果是一样的,我得到了一个500错误,而不是404错误。为了解释我在这里试图实现的是-我需要得到一个发送回调用类的字符串,以帮助long在调用REST端点时找到失败的确切原因。getUserPreference抛出一个RuntimeException,该字符串作为errorMessage。