如何使用具有多种响应类型的 RestTemplate?

How to use RestTemplate with multiple response types?

我正在使用 spring RestTemplatexml 网络服务后端通信,如下所示:

ResponseEntity<MainDTO> dto = restTemplate.postForObject(url, postData, MainDTO.class);

问题:对于正常数据,后端可能会响应 MainDTO,如果出现故障,则可能会响应 ErrorDTO。但两者都带有 HTTP 200.

但我不知道之前哪个对象会回来!无论如何 restTemplate 要求我之前通过 class 类型。

那么,我如何将 xml 解析为正常或错误 bean?

旁注:我无法控制网络服务后端。

如您所想,问题是后端 应该 return 您使用 HTTP 错误代码出错,这就是它们的用途。

但是正如您所说,您无法控制后端,因此您可以先将其作为字符串获取

ResponseEntity<String> dto = restTemplate.postForObject(url, postData, String.class);

然后你可以尝试用 Jackson 或 Gson 将字符串响应解析为 MainDTO(无论你在你的项目中有什么,你应该这样做,因为我相信 Spring 的 RestTemplate 使用它们中的任何一个在内部)用 try/catch 如果它失败,那么你尝试用你的 ErrorDto.

来解析它

更新

哦,我刚看到是XML的服务,不是JSON上的,上面的方法仍然有效,只是不用Jackson或者[=16] =],你可以使用 SimpleXML (http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#deserialize),它允许你以 "easy" 的方式反序列化 XML,你只需要用描述的注释来注释你的模型在他们的教程示例.

这个 Spring 的示例 (http://spring.io/guides/gs/consuming-rest-xml-android/) 也可能提供有关如何使用 SimpleXML 的见解。

您可以实施自定义 ResponseErrorHandler,将错误响应转换为 RuntimeException。 HTTP 消息到 POJO 的转换可以通过重新使用 RestTemplate#setMessageConverters 正在使用的 messageConverter 来完成。

是一个利用它的例子。

我有同样的问题,所以我有一个描述错误的摘要 class。我所有的 Json classes 然后扩展了抽象错误 class。所以响应对象填充了实体数据和一个我可以轻松检查的错误。

我不是特别喜欢这个解决方案,但是当我立即将 Json 对象转换为应用程序数据对象时,感觉还不错。

使用 Instanceof

MyObject1 a=null;
MyObject2 b=null;
ResponseEntity<Object>response=template.exchange(builder.build().encode().toUri(),HttpMethod.GET,entity, Object.class);
if (response.getBody() instanceof MyObject1)
    a= (MyObject1) response.getBody();
else if(response.getBody() instanceof MyObject2)
    b= (MyObject2) response.getBody();

我尝试了 但由于 Object.class:

我得到了一个异常
Method threw 'org.springframework.web.client.HttpClientErrorException' exception.

如果您使用不同的 class,它将被转换并且您将无法使用实例。

使用以下代码解决了我的问题:

String xml = restTemplate.getForObject(url, String.class, uriVariables);
JAXBContext jaxbContext = JAXBContext.newInstance();
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringSource xmlStr = new StringSource(xml);
Object o = jaxbUnmarshaller.unmarshal((Source) xmlStr);
if (o instanceof VonAZRAZRBestaetigungMeldung090098) {
    // ...
}

我遇到了同样的问题,我是这样解决的:

我创建了一个 Response class 并在其中放置了两个响应对象。 我已经注意到所有三个 class 和

@XmlRootElement
@XmlAccessorType (XmlAccessType.FIELD)

ResponseEntity <Response> responseEntity = restTemplate.postForEntity (url, request, Response.class);
Object res = responseEntity.getBody ();

if (res! = null) {
    if (res instanceof MainDTO) {
        ...
    } else if (res instanceof ErrorDTO) {
        ...
    }
}

希望有用!