当HTTP请求的返回状态为401时,如何解析Java中的响应正文
我正在使用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());
以上是 当HTTP请求的返回状态为401时,如何解析Java中的响应正文 的全部内容, 来源链接: utcz.com/qa/434708.html