当前位置: 首页 > 面试题库 >

当HTTP请求的返回状态为401时,如何解析Java中的响应正文

娄阳舒
2023-03-14
问题内容

我正在使用Spring RestTemplate和Jackson 的RESTful JSON API 。在某些情况下,我们可能会收到Status 401带有自定义JSON主体的(未经授权)响应,该响应由API制造商定义,如下所示:

{
    "code": 123,
    "message": "Reason for the error"
}

我们需要解析主体,并code在业务逻辑中使用该属性。

这是我们需要解析为的错误响应Java对象:

public class CustomError {

    @JsonProperty
    private Integer code;
    @JsonProperty
    private String message;

    public Integer getCode() {
       return code;
    }
    public String getMessage() {
        return message;
    }
}

还有一个自定义错误处理程序可以做到这一点:

public class CustomErrorHandler extends DefaultResponseErrorHandler {
    private RestTemplate restTemplate;
    private ObjectMapper objectMapper;
    private MappingJacksonHttpMessageConverter messageConverter;


    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return super.hasError(response);
    }

    @Override
    public void handleError(final ClientHttpResponse response) throws IOException {

        try {
            CustomError error = 
                (CustomError) messageConverter.read(CustomError.class, response);
            throw new CustomErrorIOException(error, error.getMessage());
        } catch (Exception e) {
            // parsing failed, resort to default behavior
            super.handleError(response);
        }
    }
}

错误处理程序失败,并HttpMessageNotReadableException在try块中显示:

“无法读取JSON:由于服务器身份验证,在流模式下无法重试”

这就是我发送请求的方式:

restTemplate.postForObject(url, pojoInstance, responseClass);

如果使用普通的旧客户端客户端程序(如Postman)执行相同的请求,则将收到预期的JSON响应。因此,我认为问题可能出在Spring的ClientHttpResponse实现中,在401状态下,它不允许访问响应主体。

是否确实可以解析响应主体?

更新资料

根据我的调查,RestTemplate该类使用ClientHttpResponse,进而创建sun.net.www.protocol.http.HttpURLConnection提供输入流的。在这里,输入流被忽略,并IOException抛出:

在流模式下,由于服务器身份验证而无法重试

因此,HttpURLConnection的实现导致了此问题。

可以避免这个问题吗?也许我们应该使用一种替代实现,在出现错误状态代码的情况下,它不忽略响应主体?您能推荐任何其他选择吗?


问题答案:

尝试以下方法而无需自定义处理程序。这个想法是从HttpStatusCodeException获取作为字符串的响应,然后可以将其转换为对象。对于转换,我使用了Jackson的ObjectMapper:

        try {

            restTemplate.postForObject(url, pojoInstance, responseClass);

        } catch (HttpStatusCodeException e) {

            if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {

                String responseString = e.getResponseBodyAsString();

                ObjectMapper mapper = new ObjectMapper();

                CustomError result = mapper.readValue(responseString,
                        CustomError.class);
            }
        }

更新: 使用另一家工厂也可能会有所帮助,因为默认工厂中存在一个与您的问题相关的错误(请参见下面的评论):

RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());


 类似资料:
  • 我正在使用Spring的RestTemplate和Jackson使用一个RESTful JSON API。在某些情况下,我们可能会收到带有自定义JSON主体的(未经授权)响应,该主体由API制造商定义,如下所示: 我们需要解析主体,并在业务逻辑中使用属性。 这是我们需要解析的错误响应Java对象: 以及一个自定义错误处理程序来执行此操作: 错误处理程序失败,在try块中出现了一个: 无法读取JSO

  • 问题内容: 我已经实现了IErrorHandler来处理在我的宁静WCF服务的构造函数中引发的授权异常。当捕获到一般异常时,将按预期返回我的自定义类型,但是ContentType标头不正确。 但是,当错误处理程序尝试返回401未经授权的http状态代码时,消息正文将覆盖为默认类型,但ContentType标头应为原样。 显然这里有问题,但我不确定是什么。 如何实现IErrorHandler,使其以

  • 下面是我正在使用的一段代码: 期望reponse conatins的状态行:“HTTP/1.1400坏请求”想知道这是可以实现的吗?如果是,那么我如何继续做同样的事情。

  • 我有一个Restendpoint,如果没有产品,它将返回204,以及以下通用角度服务: 和 但是,当服务生成 204 代码时,我收到以下错误: TypeError:无法读取null的属性“status” 这怎么可能发生?如果 API 以 204 响应,为什么整个响应为空?

  • 关于Spring Boot Webflux 2.5.0以及如何处理没有主体的http响应的小问题。 我所说的“没有身体”是指: 例如,我使用rest API并且没有控制的web应用程序返回: 使用Spring Webflux,我们可以轻松地编写如下内容: 以便获得与http正文相对应的POJO。 有什么需要帮忙的吗? 谢谢。

  • 问题内容: 我正在使用Java访问HTTPS站点,该站点以XML格式返回显示内容。我在URL本身中传递了登录凭据。这是代码片段: 我正在程序中创建一个不验证签名/未签名证书的信任管理器。但是,在运行上面的程序时,出现错误服务器返回HTTP响应代码:401表示URL:https:// Administrator:Password @ localhost:8443 / abcd 我可以在浏览器中使用相