gpt4 book ai didi

java - 使用@JsonAnySetter 映射jackson 返回带有javassist 类的Unrecognized 字段

转载 作者:行者123 更新时间:2023-11-30 12:07:09 29 4
gpt4 key购买 nike

我正在尝试在 tomcat 8.5 上使用 jersey 在其余 WS 中使用 jackson 将 json 字符串转换为对象。

该对象是在运行时使用 javassist(信息来自数据库)创建的,并添加了一个用@JsonAnySetter/Getter 注释的“其他”映射。

当我用 buildClass("MyClass") 调用 jackson 的映射器时,它抛出 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

当 MyClass 已经在启动时加载到类路径中而不使用 buildClass 时,映射工作正常。

我猜是 Loader 有问题,但我不知道如何解决这个问题。

请审阅并提供反馈。

public class ClassFactory{
public Class<?> buildClass(String className){
ClassPool pool = ClassPool.getDefault();
Loader cl = new Loader(pool);

CtClass cc = pool.makeClass(className);
ConstPool constPool = pool.get(className).getClassFile().getConstPool();

/* */
/* field creation loop */
/* */

// other map
CtField field = CtField.make("private java.util.Map other = new java.util.HashMap();", cc);
cc.addField(field);

// add other map getter
CtClass[] paramsAny = {pool.get(String.class.getName())};
cc.addMethod(CtNewMethod.make(pool.get(Object.class.getName()), "any", paramsAny,null, "{ return this.other.get($1);}", cc));
CtMethod m = cc.getDeclaredMethod("any", paramsAny);

// add @JsonAnyGetter to other map getter
AnnotationsAttribute annotationAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag );
annotationAttribute.addAnnotation(new Annotation(JsonAnyGetter.class.getName(), constPool));
m.getMethodInfo().addAttribute(annotationAttribute);

// add other map setter
CtClass[] paramsSet = {pool.get(String.class.getName()), pool.get(Object.class.getName())};
cc.addMethod(CtNewMethod.make(pool.get("void"), "set", paramsSet,null, "{this.other.put($1,$2);}", cc));
m = cc.getDeclaredMethod("set", paramsSet);

// add @JsonAnySetter to other map setter
annotationAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag );
annotationAttribute.addAnnotation(new Annotation(JsonAnySetter.class.getName(), constPool));
m.getMethodInfo().addAttribute(annotationAttribute);

//build class
return cc.toClass(cl,null);
}
}

这是生成类的一部分

public class MyClass{
/* more fields */

private Map other = new HashMap();
@JsonAnyGetter
public Object any(String var1) {
return this.other.get(var1);
}
@JsonAnySetter
public void set(String var1, Object var2) {
this.other.put(var1, var2);
}

}

jackson 映射器

ObjectReader reader = new ObjectMapper().reader();
Class<?> myClass = new ClassFactory().buildClass("MyClass");
Object myClassInstance =reader.forType(myClass).readValue(jsonString);

一些json

{
/* more fields */
"info1":"val1",
"info2" :"val2"
}

最佳答案

JacksonClassIntrospector 无法识别来自 javaassist 类加载器的注解加载。从两个不同的类加载器加载的同一个类被认为是不同的。尝试将这些注解的加载类委托(delegate)给父类加载器。

    Loader cl = new Loader(pool);
cl.delegateLoadingOf("com.fasterxml.jackson.annotation.JsonAnySetter");
cl.delegateLoadingOf("com.fasterxml.jackson.annotation.JsonAnyGetter");

关于java - 使用@JsonAnySetter 映射jackson 返回带有javassist 类的Unrecognized 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55158903/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com