当前位置: 首页 > 知识库问答 >
问题:

SpringRESTTemplate解析自定义错误响应

凤财
2023-03-14

给Rest服务打电话

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

返回:

<widget>
  <id>123</id>
  <name>Foo</name>
  <manufacturer>Acme</manufacturer>
</widget>

此客户端代码的工作原理是:

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);

但是,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>

但此客户端代码引发了一个异常:

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

org.springframework.web.client.HttpClientErrorException: 404 Not Found

我试过:

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...
}

第二次调用只是抛出了另一个HttpClientErrorException,而且它觉得调用服务两次是不对的。

是否有一种方法可以调用该服务一次,并在成功时将响应解析为小部件,在未找到时解析为错误消息?

共有3个答案

闻人英韶
2023-03-14

由于您已经捕获了HttpClientErrorException对象,因此它应该允许您轻松提取有关错误的有用信息并将其传递给调用方。

例如:

try{
    <call to rest endpoint using RestTemplate>
} catch(HttpClientErrorException e){
    HttpStatus statusCode = e.getStatusCode();
    String body = e.getResponseBodyAsString();
}

如果需要将错误消息body进一步反序列化到某个相关对象中,则可以在catch语句范围之外的某个地方处理该对象。

淳于亦
2023-03-14

如果愿意,还可以从错误响应主体创建对象

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

MyClass obj = om.readValue(errorResponse, MyClass.class);
陆洛城
2023-03-14

根据我的评论,我检查了JavaDoc,它确实支持设置/获取statusText以及响应Body。然而,它们是可选的,RestTem板可能无法填充它们-您需要尝试以下内容:

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)
}

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

 类似资料:
  • 问题内容: 我已经编写了REST API服务,该服务要求所有响应均为JSON。但是,当Go HTTP请求解析器遇到错误时,它将返回400作为纯文本响应,而无需调用我的处理程序。例: 请注意无效的授权标头。当然,400是正确的响应,但是当然是文本/纯文本。有什么方法可以配置Go http解析器以使用自定义错误响应媒体类型和主体? 问题答案: 你不能 您可以在net / http源中找到它,只有在请求

  • Apache可以让网站管理员自己自定义对一些错误和问题的响应。 自定义的响应可以定义为当服务器检测到错误或问题时才被激活。 如果一个脚本崩溃并产生"500 Server Error"响应,那么这个响应可以被更友好的提示替换或者干脆用重定向语句跳到其他的URL(本地的或外部的)。 行为 老式的行为 Apache1.3 会响应一些对于用户没有任何意义的错误或问题信息,而且不会将产生这些错误的原因写入日

  • 请帮助我了解我应该在哪里更新失败案例的实际合同?

  • 然而,这产生了(正如怀疑的那样)完全不同的反应:

  • 我正在努力裁剪javax。验证。ConstraintValidator和javax。验证。根据我的需要限制ValidatorContext。我从格式错误的请求正文收到的响应消息始终采用以下形状: <代码> 此消息也以500而不是400错误请求的形式返回。我无法获得工作到解决方案来执行以下操作: 仅包括<代码> 我有以下代码: 向上面的代码发送格式错误的有效负载将导致如下消息: 我希望能够收到以下信