java 使用匿名类的Jackson化

llycmphe  于 11个月前  发布在  Java
关注(0)|答案(4)|浏览(82)

我一整天都在寻找答案,但到目前为止,我没有太多的运气。
我的问题很简单:如何使用Jackson正确地匿名化一个对象。

private interface Interface1
{
    int getValue();
}

public static void testAnonymousObject() throws IOException
{
    ObjectMapper mapper = new ObjectMapper();

    mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
    mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

    Interface1 testObject = new Interface1()
    {
        private final int value = 5;

        @Override
        public int getValue()
        {
           return value;
        }
    };

    String json = mapper.writeValueAsString(testObject);
    System.out.println("JSON = " + json);

    Interface1 received = (Interface1) mapper.readValue(json, Object.class);
    System.out.println(received);
}

字符串
在我得到一个异常之前,它的输出是:JSON = [“com.foo.test.JacksonTest$1”,{“value”:5}]:

  • 线程“main”中出现异常com.fasterxml.Jackson.databind.JsonMappingException:无法将Class com.foo.test.JacksonTest$1(类型为local/anonymous)转换为Bean*。
    编辑澄清一下,Jackson和XStream都能序列化对象。但似乎只有XStream能将对象序列化回去。所以这个场景可以工作。
mutmk8jj

mutmk8jj1#

在我写这篇文章的时候,似乎Jackson没有正确地序列化内部类或匿名类,而其他软件包,如XStream和Kryo,却做到了。

pcrecxhr

pcrecxhr2#

因为内部类没有默认的零参数构造函数(它们有一个对外部/父类的隐藏引用),所以Jackson不能示例化它们。
你可以检查this link

knsnq2tg

knsnq2tg3#

问题不仅在于它是一个内部类(这可能有问题,也可能没有问题,取决于实现是静态的还是非静态的),而且还在于它没有包含类型信息--Jackson看到的所有类型都是Interface1。为了使阅读回它,必须包含类型信息(“多态类型处理”),或者指定抽象类型和实现类之间的Map。
假设你使用的是匿名内部类,你可以通过启用所谓的“默认类型”来支持这种用法(参见ObjectMapper javadocs for enableDefaultTyping()或类似的东西)。但是如果你不想为所有非final类型启用类型包含,你可能还需要实现特定的策略。
要查看是否包含type id,您可以使用其中一个默认选项启用默认类型,并查看正在生成的JSON:应该有一个额外的type id(当类名用作id时,“@class”属性)。

8ehkhllq

8ehkhllq4#

一个现成的代码片段,用于使用嵌套类将通用JSON转换为带有Jackson的Java POJO:

static class MyJSON {

    private Map<String, Object> content = new HashMap<>();

    @JsonAnySetter
    public void setContent(String key, Object value) {
        content.put(key, value);
    }
}

String json = "{\"City\":\"Prague\"}";

try {

    MyPOJO myPOJO = objectMapper.readValue(json, MyPOJO.class);

    String jsonAttVal = myPOJO.content.get("City").toString();

    System.out.println(jsonAttVal);

} catch (IOException e) {
    e.printStackTrace();
}

字符串
@JsonAnySetter确保了通用的JSON解析和填充。

相关问题