我的应用程序有两个模块:API A 和可视化组件 V 。
某些API模型类通过org.codehaus.jackson.annotation
进行注释(杰克逊1.9.13)。在一种逻辑流程中,基于这些模型的对象将进行JSON序列化,然后交付给 V 。
V 当前使用com.fasterxml.jackson.core.ObjectMapper
(杰克逊2.9.1)反序列化接收到的对象。 ( V 确实具有 A 作为依赖项,因此在类路径中也传递了Jackson 1.9.13。)
由于Jackson 2.9.1试图将数据反序列化为Jackson 1.9.13带注释的类,因此自定义枚举名称映射之类的某些功能无法正常工作。例如:
enum Size {
XL("Extra Large"),
L("Large"),
M("Medium"),
S("Small"),
XS("Extra Small");
private String name;
Size(String name) {
this.name = name;
}
public String getName() {
return name;
}
@org.codehaus.jackson.annotate.JsonCreator
public static Size forValue(String value) {
for (Size size : Size.values()) {
if (size.getName().equals(value)) {
return size;
}
}
return null;
}
}
class Model {
String name;
Size size;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSize() {
return size.getName();
}
public void setSize(Size size) {
this.size = size;
}
}
V 无法反序列化上述Model
类中的对象,出现以下错误:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `Size` from String "Medium": value not one of declared Enum instance names: [S, XL, M, XS, L]
at [Source: (String)"{"name":"foo","size":"Medium"}"; line: 1, column: 22] (through reference chain: Model["size"])
这一切都是有道理的(因为1.9.13至2.9.1是向后不兼容的更改),但是我有什么选择?我是否必须将 V 的反序列化逻辑降级为Jackson 1.9.13?或者,是否有任何我可以“插入”以使1.9.13注释在2.9.1下工作的“适配器”或配置?
(此时,我不希望将 A 升级到2.9.1,因为 A 的总体包装尺寸是一个主要问题;请切换为{{1 }}会将 A 的所有Jackson依赖项大小从980 KB增加到1.51 MB-这是不可接受的,因为完整的核心捆绑包(基于 A ;不包括 V )的大小目前不足8 MB。
答案 0 :(得分:0)
您可以通过实现com.fasterxml.jackson.databind.AnnotationIntrospector
类来自定义注释处理。例如,如果我们要允许在模型中使用org.codehaus.jackson.annotate.JsonCreator
批注,则需要为其实现处理程序。在其他情况下,它将被忽略。简单的实现可能如下所示:
class CodehausAnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated a) {
JsonCreator.Mode mode = super.findCreatorAnnotation(config, a);
if (mode != null) {
return mode;
}
org.codehaus.jackson.annotate.JsonCreator ann = _findAnnotation(a, org.codehaus.jackson.annotate.JsonCreator.class);
if (ann != null) {
return JsonCreator.Mode.DEFAULT;
}
return null;
}
}
在使用org.codehaus.jackson.annotate.JsonCreator
注释的情况下,我们只需启用DEFAULT模式。下面的代码显示了如何注册新的自省者:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
public class JsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new CodehausAnnotationIntrospector());
Model model = new Model();
model.setName("Model1");
model.setSize(Size.XL);
String json = mapper.writeValueAsString(model);
System.out.println(json);
System.out.println(mapper.readValue(json, Model.class));
}
}
上面的代码显示:
{"name":"Model1","size":"Extra Large"}
Model{name='Model1', size=XL}