【发布时间】:2019-03-14 09:24:23
【问题描述】:
我正在尝试在 Tomcat 8.5 上使用 jersey 在 rest WS 中使用 jackson 将 json 字符串转换为对象。
对象是在运行时使用 javassist 创建的(信息来自 db)并添加一个用 @JsonAnySetter/Getter 注释的“其他”映射。
当我用 buildClass("MyClass") 调用 jackson 的映射器时,它会抛出 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException。
如果 MyClass 在启动时已加载到类路径中而不使用 buildClass,则映射工作正常。
我猜是加载器问题,但我不知道如何解决这个问题。
请查看并提供反馈。
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);
}
}
杰克逊映射器
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"
}
【问题讨论】:
标签: java json jackson javassist