我需要反序列化外部REST API的响应,通常是JSON对象,但如果发生错误,它将是JSON对象的数组。API缺少文档,因此我通过响应的HTTP Status
确定是否发生错误。问题是每个API路由的非错误响应具有不同的结构(用户响应、产品响应等)。另一个问题是,在我的应用程序中,我们使用了一个抽象类进行外部API响应,其字段为error
、hasError
。我解决了这个问题,如下所示:
public abstract class AbsractApiResponse {
public abstract String getError();
public abstract void setError(String error);
public abstract String getDescription();
public abstract void setDescription(String error);
}
public class ErrorResponse {
private String errorCode; // getters/setters
private String message; // getters/setters
}
public class UserResponse extends AbsractApiResponse {
private String error; // getters/setters
private boolean hasError; // getters/setters
private boolean description; // getters/setters
private String userName;
private String userEmail;
}
public <R extends AbsractApiResponse> R deserializeResponse(
String apiResponse, Class<R> responseType, boolean isHttpError)
throws JsonProcessingException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
R response;
Object deserialized = objectMapper.readValue(apiResponse, Object.class);
if (isHttpError && deserialized instanceof List) {
TypeReference<List<ErrorResponse>> errorResponseType = new TypeReference<>() {};
List<ErrorResponse> responseErrors = objectMapper.convertValue(deserialized,
errorResponseType);
Constructor<R> constructor = responseType.getDeclaredConstructor();
response = constructor.newInstance();
ErrorResponse firstError = responseErrors.get(0);
String errorDescription = responseErrors.stream().map(ErrorResponse::toString).collect(Collectors.joining());
response.setError(firstError.getMessage());
response.setDescription(errorDescription);
} else {
response = objectMapper.convertValue(deserialized, responseType);
}
return response;
}
用这种方法我不得不添加像error
/hasError
这样的字段到每个类中,这些字段代表了一个响应,我想这并不是那么糟糕。另一个危险信号是反射(responseType.getDeclaredConstructor()
)的使用和伴随它的4个检查异常。我想知道,是否有更好的方法来解决这个问题?
1条答案
按热度按时间bbmckpt71#
我不建议把错误响应和业务对象合并在一起,成功的时候可以返回给定的响应类,出错的时候抛出异常,我认为这是最干净的方式。
如果你不想抛出异常,你可以实现包含
response
和error
对象的 Package 类。如果设置了error
字段,我们就知道有问题。它可能如下所示:该方法一般实现可以如下所示: