序列化Java对象时,由于它利用了反射,因此Jackson会在其运行时表示中序列化该对象。
我有以下课程:
@lombok.AllArgsConstructor
@lombokGetter
class ErrorInformation {
private final Exception exception;
}
和
final ErrorInformation errorInfo = new ErrorInformation(new IllegalArgumentException("foo"));
Jackson不仅序列化了Exception
,实际上还序列化了IllegalArgumentException
中的所有字段-产生了不可控制的后果,例如循环引用(请参见mostSpecificCause
中的org.springframework.web.client.HttpServerErrorException
)。 / p>
我怎么能告诉杰克逊实际上只序列化Exception
的信息,而不考虑实际的运行时类型,就像您希望从像Java这样的静态类型化语言中期望的那样?
答案 0 :(得分:3)
Jackson
默认情况下序列化给定getters
中的所有POJO
方法。如果我们要序列化3-rd party
类,则需要注意周期和其他问题。为此,我们可以使用MixIn
feature。我们需要定义所有NestedRuntimeException
异常,我们要忽略getMostSpecificCause
方法。
interface NestedRuntimeExceptionMixIn {
@JsonIgnore
Throwable getMostSpecificCause();
}
用法示例:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.core.NestedRuntimeException;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpServerErrorException;
public class JsonApp {
public static void main(String[] args) throws Exception {
HttpServerErrorException exception = new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "error");
ErrorInformation ei = new ErrorInformation(exception);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.addMixIn(NestedRuntimeException.class, NestedRuntimeExceptionMixIn.class);
System.out.println(mapper.writeValueAsString(ei));
}
}
打印:
{
"exception" : {
"cause" : null,
"stackTrace" : [ {
"methodName" : "main",
"fileName" : "JsonApp.java",
"lineNumber" : 13,
"className" : "JsonApp",
"nativeMethod" : false
} ],
"rawStatusCode" : 500,
"statusText" : "error",
"responseHeaders" : null,
"statusCode" : "INTERNAL_SERVER_ERROR",
"responseBodyAsByteArray" : "",
"responseBodyAsString" : "",
"message" : "500 error",
"rootCause" : null,
"localizedMessage" : "500 error",
"suppressed" : [ ]
}
}
答案 1 :(得分:2)
由于我们无法更改IllegalArgumentException
类的逻辑,因此可以在ErrorInformation
类中创建其他实例字段,并在其中填充要序列化的信息,并将exception
变量标记为{ {1}}
例如假设您要保存错误消息信息。因此,创建一个transient
字段,例如String
,并在构造函数中填充错误消息信息。下面是示例代码。
errorMessage
反序列化时,您可以使用此错误消息信息来创建已序列化的异常对象的相似(不相同)实例