Spring RestTemplate解析自定义错误响应

Pau*_*kin 9 rest spring-mvc

给定REST服务调用

http://acme.com/app/widget/123

收益:

<widget>
  <id>123</id>
  <name>Foo</name>
  <manufacturer>Acme</manufacturer>
</widget>
Run Code Online (Sandbox Code Playgroud)

此客户端代码有效:

RestTemplate restTemplate = new RestTemplate();
XStreamMarshaller xStreamMarshaller = new XStreamMarshaller();
xStreamMarshaller.getXStream().processAnnotations(
    new Class[] { 
        Widget.class,
        ErrorMessage.class
    });

HttpMessageConverter<?> marshallingConverter = new MarshallingHttpMessageConverter(
    xStreamMarshaller, xStreamMarshaller);

List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
    converters.add(marshallingConverter);

restTemplate.setMessageConverters(converters);

Widget w = restTemplate.getForObject(
    "http://acme.com/app/widget/{id}", Widget.class, 123L);
Run Code Online (Sandbox Code Playgroud)

但是,调用http://acme.com/app/widget/456会返回:

<error>
    <message>Widget 456 does not exist</message>
    <timestamp>Wed, 12 Mar 2014 10:34:37 GMT</timestamp>
</error>
Run Code Online (Sandbox Code Playgroud)

但是此客户端代码抛出异常:

Widget w = restTemplate.getForObject(
    "http://acme.com/app/widget/{id}", Widget.class, 456L);

org.springframework.web.client.HttpClientErrorException: 404 Not Found
Run Code Online (Sandbox Code Playgroud)

我试过了:

try {
    Widget w = restTemplate.getForObject(
       "http://acme.com/app/widget/{id}", Widget.class, 456L);
}
catch (HttpClientErrorException e) {
    ErrorMessage errorMessage = restTemplate.getForObject(
       "http://acme.com/app/widget/{id}", ErrorMessage.class, 456L);

   // etc...
}
Run Code Online (Sandbox Code Playgroud)

第二次调用只是抛出了另一个HttpClientErrorException,而且它感觉不适合两次调用服务.

有没有办法调用服务一次,并在成功时将响应解析为Widget,如果找不到,则解析ErrorMessage?

nic*_*dos 11

根据我的评论,我检查了HttpClientErrorExceptionJavaDoc,它确实支持设置/获取statusText以及responseBody.但是它们是可选的,RestTemplate可能不会填充它们 - 你需要尝试类似的东西:

try {
    Widget w = restTemplate.getForObject(
       "http://acme.com/app/widget/{id}", Widget.class, 456L);
}
catch (HttpClientErrorException e) {
    String responseBody = e.getResponseBodyAsString();
    String statusText = e.getStatusText();
    // log or process either of these...
    // you'll probably have to unmarshall the XML manually (only 2 fields so easy)
}
Run Code Online (Sandbox Code Playgroud)

如果它们都是空/ null,那么您可能必须扩展所涉及的RestTemplate类并自己填充这些字段和/或在Spring站点上引发Jira问题.


zyg*_*tus 5

如果您愿意,还可以从错误响应正文创建对象:

ObjectMapper om = new ObjectMapper();
String errorResponse = ex.getResponseBodyAsString();

MyClass obj = om.readValue(errorResponse, MyClass.class);
Run Code Online (Sandbox Code Playgroud)