当前位置: 首页 > 知识库问答 >
问题:

用@JSONanySetter映射jackson返回javassist类无法识别的字段

叶经略
2023-03-14

我试图在Tomcat8.5上使用jersey在rest WS中使用jackson将一个json字符串转换为一个对象。

对象是在运行时使用javassist(信息来自db)创建的,并添加一个用@jsonanysetter/getter注释的“other”映射。

当我使用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"
}

共有1个答案

齐建安
2023-03-14

jacksonClassInspector无法识别从JavaAssist类加载器加载的注释。从两个不同的类加载器加载的相同类被认为是不同的。尝试将加载类委托给这些注释的父类加载器。

    Loader cl = new Loader(pool);
    cl.delegateLoadingOf("com.fasterxml.jackson.annotation.JsonAnySetter");
    cl.delegateLoadingOf("com.fasterxml.jackson.annotation.JsonAnyGetter");
 类似资料:
  • 我是新来的spring boot,我的问题很简单,但我找不到问题出在哪里。 我有一个基本的@GetMapping和@DeleteMapping 我正在用邮递员测试,获取请求正在工作,但删除请求不起作用。即使当我调试Spring启动应用程序时。GetMap被调用,而删除没有“反应” /called 也许信息还不够,但我甚至测试了@DeleteMapping(“/test2”)没有做任何事情,我的意思

  • 我想询问一个人,并得到以下回应: 但在需要时,我还想包含字段,并获得如下内容: 但是,我得到的只是手机ID,就像这样: 这是两个有问题的领域:

  • 我正在尝试使用Jackson将一些JSON转换为包含一些简单字符串和另一个类的类的实例,我正在使用@JsonCreator。似乎Jackson无法创建其他类的实例。 问题是,当我作为测试的一部分运行此代码时: 我得到以下例外: 我试图在简单测试中解析的JSON如下所示: 我有一个看起来有点像这样的类“播放器” 另一个类“字符”看起来像这样 对于像这样的小数据集,会有更好的方法来构建整个事情,但我认

  • 我正在使用IntelliJ IDEA,并且Spring的所有插件都被激活了,但是当我加载我的Maven项目时,我遇到了以下错误: Spring配置检查 找到未映射的Spring配置文件。 请为模块配置/设置Spring刻面 有什么想法阻止它自动配置?

  • 我使用http://jsonlint.com来验证JSON是否有效。因此,我要么需要更改JSON或代码,要么可能两者都需要。有什么想法吗?

  • 我正在用Java/Spring创建简单的rest客户端。我的请求已被远程服务正确使用,我得到了以下响应字符串: 下面的代码是对象,我想从Json响应绑定值 我一直在获得“无法识别的字段访问\u令牌”,但当我添加