Iva*_*vov 21 java api spring jackson resttemplate
我正在使用Spring RestTemplate和Jackson 来使用RESTful JSON API .在某些情况下,我们可能会收到一个Status 401(未经授权的)响应,其中包含由API制造商定义的自定义JSON主体,如下所示:
{
"code": 123,
"message": "Reason for the error"
}
Run Code Online (Sandbox Code Playgroud)
我们需要解析主体,并code在业务逻辑中使用该属性.
这是我们需要解析的错误响应Java对象:
public class CustomError {
@JsonProperty
private Integer code;
@JsonProperty
private String message;
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}
Run Code Online (Sandbox Code Playgroud)
和自定义错误处理程序执行此操作:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
错误处理程序HttpMessageNotReadableException在try块中失败:
"无法读取JSON:由于服务器身份验证无法在流模式下重试"
这就是我发送请求的方式:
restTemplate.postForObject(url, pojoInstance, responseClass);
Run Code Online (Sandbox Code Playgroud)
如果使用普通的旧休息客户端程序(如Postman)执行相同的请求,则会收到预期的JSON响应.所以,我认为问题可能是Spring的ClientHttpResponse实现以某种方式不允许访问响应体,如果是401状态.
是否确实可以解析响应主体?
更新
根据我调查的内容,RestTemplate该类使用ClientHttpResponse了反过来创建一个sun.net.www.protocol.http.HttpURLConnection提供输入流的类.它就在那里,输入流被忽略并被IOException抛出:
在流模式下,由于服务器身份验证无法重试
因此,该HttpURLConnection实施正在引发这个问题.
是否可以避免这个问题?也许我们应该使用一个替代实现,在错误状态代码的情况下不会忽略响应主体?你能推荐任何替代品吗?
Mar*_*ios 40
无需自定义处理程序即可尝试以下方法.我们的想法是将响应作为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);
}
}
Run Code Online (Sandbox Code Playgroud)
更新: 使用其他工厂也可能有所帮助,因为与您的问题相关的默认错误存在错误(请参阅下面的评论):
RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35087 次 |
| 最近记录: |