thu*_*rmc 6 spring json spring-mvc jackson jackson-databind
我必须升级几个包才能通过 whitesource 安全扫描,现在升级了依赖项HttpMessageConverter,以前拦截和构建响应的自定义不再有效。相关的依赖升级如下所示。
Tomcat 嵌入核心 8.5.50 -> 9.0.30
Spring Cloud 合约发布 2.0.1.RELEASE-> 2.0.6.RELEASE
Spring Boot 版本 2.0.4.RELEASE -> 2.0.6.RELEASE
杰克逊数据绑定 2.9.6 -> 2.10.0.pr1
杰克逊核心:2.10.1 -> 2.10.0.pr1
这是以前工作的自定义 HttpMessageConverter:
private class JsonApiHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
JsonApiHttpMessageConverter() {
super(MediaType.valueOf(ResponseType.MEDIA_TYPE_JSON_API));
}
@Override
protected boolean supports(final Class<?> clazz) {
return clazz == HttpErrorResponse.class;
}
@Override
protected Object readInternal(final Class<?> clazz, final HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
protected void writeInternal(final Object o, final HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
try (OutputStreamWriter outputStream =
new OutputStreamWriter(outputMessage.getBody(), Charset.defaultCharset())) {
JsonAPIDocument document;
if (o instanceof HttpErrorResponse) {
// Build Error Document
final HttpErrorResponse errorResponse = (HttpErrorResponse) o;
final JsonApiErrorDTO errorDTO = new JsonApiErrorDTO(Integer.toString(errorResponse.getStatus()),
Integer.toString(errorResponse.getCode()), errorResponse.getMessage());
document = new JsonAPIDocument();
document.addError(errorDTO);
} else { // Build JSON API Response Document
final JsonApiDocumentBuilder documentBuilder = new JsonApiDocumentBuilder();
documentBuilder.data(o);
document = documentBuilder.build();
}
outputStream.write(new Gson().toJson(document));
outputStream.flush();
} catch (final InvalidJsonApiObjectException ijaoe) {
LOG.error("Error in converting Object to JsonAPIDocument", ijaoe);
throw new ServiceException(ijaoe);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它是在一个类中定义的,该类注册了如下所示的消息转换器
@Configuration
public class ServiceConfiguration implements WebMvcConfigurer {
...
@Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
converters.add(new JsonApiHttpMessageConverter());
converters.add(new ByteArrayHttpMessageConverter());
converters.add(new StringHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter());
converters.add(new SourceHttpMessageConverter<>());
converters.add(new AllEncompassingFormHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter());
converters.add(new MappingJackson2CborHttpMessageConverter());
converters.add(new Jaxb2RootElementHttpMessageConverter());
}
@Override
public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.valueOf(ResponseType.MEDIA_TYPE_JSON_API));
}
}
Run Code Online (Sandbox Code Playgroud)
这是错误响应代码:
@XmlRootElement(name = "error")
@XmlAccessorType(XmlAccessType.FIELD)
@JsonApiType(type = "error")
public class HttpErrorResponse implements Serializable {
private static final long serialVersionUID = 1321088631120274988L;
@XmlTransient
private int status;
@XmlElement(name = "code", required = true)
private int code;
@XmlElement(name = "message", required = true)
@JsonApiAttribute(name = "detail")
private String message;
@JsonApiIgnore
@XmlElement(name = "uuid", required = true)
private String uuid;
public HttpErrorResponse() {
this.uuid = UUID.randomUUID().toString();
}
public HttpErrorResponse(final int status, final int code, final String message) {
this();
this.status = status;
this.code = code;
this.message = message;
}
public int getStatus() {
return status;
}
public void setStatus(final int status) {
this.status = status;
}
public int getCode() {
return code;
}
public void setCode(final int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(final String message) {
this.message = message;
}
public String getUuid() {
return uuid;
}
public void setUuid(final String uuid) {
this.uuid = uuid;
}
}
Run Code Online (Sandbox Code Playgroud)
并且该对象似乎确实是返回的对象,但消息转换器并未对其进行转换。转换器工作的旧响应格式是:
"{\"included\":[],\"errors\":[{\"status\":\"400\",\"code\":\"990002\",\"detail\":\"Invalid subscription id: XYZ\"}]}",
Run Code Online (Sandbox Code Playgroud)
目前的回应是:
"responseBody": "{\"status\":400,\"code\":990002,\"message\":\"Invalid subscription id: XYZ\",\"uuid\":\"018fe1e3-3936-4c53-8612-61ef778fd811\"}",
Run Code Online (Sandbox Code Playgroud)
如果我的问题不清楚,我很抱歉,如果有什么我遗漏了,请告诉我。我很困惑为什么转换器不再拦截响应并更新格式。这里也是转换器应该构建的格式:
@JsonPropertyOrder({ "data", "included", "errors" })
@JsonInclude(JsonInclude.Include.NON_NULL)
public class JsonAPIDocument extends AbstractJsonAPIDocument {
@JsonInclude(JsonInclude.Include.NON_NULL)
private IJsonAPIDTO data;
@JsonInclude(JsonInclude.Include.NON_NULL)
public IJsonAPIDTO getData() {
return data;
}
public void setData(IJsonAPIDTO data) {
this.data = data;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是响应头:
"responseHeaders": {
"X-Origin-Ref": "microservice",
"X-Transaction-Ref": "b2e3d807-0d6f-40e7-90ad-43d5ecb455c2",
"Content-Type": "application/vnd.api+json"
}
Run Code Online (Sandbox Code Playgroud)
和 ResponseType.MEDIA_TYPE_JSON_API 是
public static final String MEDIA_TYPE_JSON_API = "application/vnd.api+json"
Run Code Online (Sandbox Code Playgroud)
作为绝望的尝试,我将 JsonApiHttpMessageConverter 类的支持方法更改为始终返回 true 并且转换器仍然没有接收响应
| 归档时间: |
|
| 查看次数: |
192 次 |
| 最近记录: |