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

11 浏览
0 Comments

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

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

{

"code": 123,

"message": "错误原因"

}

我们需要解析这个主体,并在业务逻辑中使用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) {
            // 解析失败,使用默认行为
            super.handleError(response);
        }
    }
}

尝试块中的错误处理程序会失败,并显示HttpMessageNotReadableException

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

这是我发送请求的方式:

restTemplate.postForObject(url, pojoInstance, responseClass);

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

确实存在解析响应主体的可能性吗?

更新

根据我的调查,RestTemplate类使用ClientHttpResponse,后者又创建了一个sun.net.www.protocol.http.HttpURLConnection,该类提供输入流。在那里,输入流被忽略并抛出一个IOException

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

所以,HttpURLConnection的实现导致了这个问题。

有可能避免这个问题吗?也许我们应该使用一个不会在错误状态码的情况下忽略响应主体的替代实现?你能推荐一些替代方案吗?

0