使用类名作为JSON Jackson序列化的根密钥

Dan*_*nDC 27 java serialization json jackson

假设我有一个pojo:

import org.codehaus.jackson.map.*;

public class MyPojo {
    int id;
    public int getId()
    { return this.id; }

    public void setId(int id)
    { this.id = id; }

    public static void main(String[] args) throws Exception {
        MyPojo mp = new MyPojo();
        mp.setId(4);
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
        System.out.println(mapper.getSerializationConfig().isEnabled(SerializationConfig.Feature.WRAP_ROOT_VALUE));
        System.out.println(mapper.writeValueAsString(mp));
    }
}
Run Code Online (Sandbox Code Playgroud)

当我使用Jackson ObjectMapper进行序列化时,我得到了

true
{"id":4}
Run Code Online (Sandbox Code Playgroud)

但我想要

true
{"MyPojo":{"id":4}}
Run Code Online (Sandbox Code Playgroud)

我一直在搜索,Jacksons的文档真的没有组织,而且大部分已经过时了.

Aru*_*ash 32

通过@JsonTypeInfo在类级别添加jackson注释,您可以获得预期的输出.我刚刚在课堂上添加了无变化.

package com.test.jackson;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;

@JsonTypeInfo(include=As.WRAPPER_OBJECT, use=Id.NAME)
public class MyPojo {
    // Remain same as you have
}
Run Code Online (Sandbox Code Playgroud)

输出:

{
    "MyPojo": {
        "id": 4
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 完善.为我工作.有没有办法将描述符更改为不是类名?喜欢`mypojo`而不是'MyPojo`? (3认同)
  • `@JsonTypeName("foo") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT ,use = JsonTypeInfo.Id.NAME)` (3认同)

Ait*_*ito 25

我没有使用杰克逊,但搜索我发现这个配置似乎是你想要的:WRAP_ROOT_VALUE

可以启用以在单个属性JSON对象中包含的根值(通常是JSON对象但可以是任何类型)的功能,其中key作为"根名称",由注释introspector确定(尤其是对于使用@XmlRootElement的JAXB) .name)或后备(非限定类名).功能主要用于JAXB兼容性.

默认设置为false,表示未包装根值.

这样您就可以配置映射器:

objectMapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
Run Code Online (Sandbox Code Playgroud)

我希望它可以帮助你......

  • 欢迎来到Jacksons的古怪世界,记录那些实际上不起作用的功能.谢谢你的帮助. (6认同)
  • 另请参阅[JACKSON-630](http://jira.codehaus.org/browse/JACKSON-630),这导致在Jackson 1.9中添加了用于配置根名称的`@JsonRootName`注释.仍必须启用`WRAP_ROOT_VALUE`才能使此注释生效. (4认同)
  • `objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);`for较新版本. (3认同)
  • 我认为跳过这么多圈去做一些像在需要时启用@JsonRootName 这样简单的事情是荒谬的。 (2认同)

小智 12

以下是实现此目的的方法

Map<String, MyPojo> singletonMap = Collections.singletonMap("mypojo", mp);
System.out.println(mapper.writeValueAsString(singletonMap));
Run Code Online (Sandbox Code Playgroud)

输出 {"mypojo":{"id":4}}

这里的优点是我们可以为json对象的根密钥命名.通过上面的代码,mypojo将成为根密钥.当我们使用像Mustache.js这样的java脚本模板来迭代json对象时,这种方法将非常有用


use*_*529 6

为了实现这一点,你需要JsonTypeInfo在你的类上使用注释,特别是WRAPPER_OBJECT

@JsonTypeName("foo")                                                                                         
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT ,use = JsonTypeInfo.Id.NAME)

public class Bar(){
)
Run Code Online (Sandbox Code Playgroud)