Jackson xml 和 json 根元素

Posted

技术标签:

【中文标题】Jackson xml 和 json 根元素【英文标题】:Jackson xml and json root element 【发布时间】:2017-11-21 21:03:36 【问题描述】:

我有一个服务以 JSON 和 XML 格式返回对象。

http://localhost:8091/apiN/xml/2

XML 结果

<restObjectList>
    <restObjectList>
        <restObjectList>
            <timestamp>2017-06-19 17:01:01</timestamp>
            <title>Rest object</title>
            <fullText>This is the full text. ID: 1</fullText>
            <id>1</id>
            <value>0.1412789210135622</value>
        </restObjectList>
        <restObjectList>
            <timestamp>2017-06-19 17:01:01</timestamp>
            <title>Rest object</title>
            <fullText>This is the full text. ID: 2</fullText>
            <id>2</id>
            <value>0.9886539664938628</value>
        </restObjectList>
    </restObjectList>
</restObjectList>

http://localhost:8091/apiN/2

JSON 结果


    "restObjectList": [
        
            "timestamp": "2017-06-19 17:01:01",
            "title": "Rest object",
            "fullText": "This is the full text. ID: 1",
            "id": 1,
            "value": 0.1412789210135622
        ,
        
            "timestamp": "2017-06-19 17:01:01",
            "title": "Rest object",
            "fullText": "This is the full text. ID: 2",
            "id": 2,
            "value": 0.9886539664938628
        
    ]

我希望收到的结果

xml

<restObjectList>
    <restObject>
        <timestamp>2017-06-19 17:01:01</timestamp>
        <title>Rest object</title>
        <fullText>This is the full text. ID: 1</fullText>
        <id>1</id>
        <value>0.1412789210135622</value>
    </restObject>
    <restObject>
        <timestamp>2017-06-19 17:01:01</timestamp>
        <title>Rest object</title>
        <fullText>This is the full text. ID: 2</fullText>
        <id>2</id>
        <value>0.9886539664938628</value>
    </restObject>
</restObjectList>

json


    "restObjectList": [
        "restObject": 
            "timestamp": "2017-06-19 17:01:01",
            "title": "Rest object",
            "fullText": "This is the full text. ID: 1",
            "id": 1,
            "value": 0.1412789210135622
        
    , 
        "restObject": 
            "timestamp": "2017-06-19 17:01:01",
            "title": "Rest object",
            "fullText": "This is the full text. ID: 2",
            "id": 2,
            "value": 0.9886539664938628
        
    ]

如何为 JSON 和 XML 包装 restObject 并为 restObjectList 修复 XML 数据,因为此标签在不同级别重复。

我的代码

RestObject

@JsonRootName(value = "restObject")
@XmlRootElement(name = "restObject")
public class RestObject implements Serializable 

    private LocalDateTime timestamp;
    private String title;
    private String fullText;
    private Long id;
    private Double value;

    //Getters, setters

RestObjectList

@JsonRootName(value = "restObjectList")
@XmlSeeAlso(RestObject.class)
public class RestObjectList 

    private List<RestObject> restObjectList;

    //Getter and setter

JacksonConfig

@Configuration
public class JacksonConfig 

    @Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) 
        ObjectMapper objectMapper = builder.createXmlMapper(true).build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//Use custom date-time format.
        objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
        objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false);
        return objectMapper;
    

    @Bean
    public ObjectMapper objectMapper() 
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
        objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
        return objectMapper;
    

【问题讨论】:

【参考方案1】:

JSON 和 XML 结构不等价。在 XML 中,您需要一个 RestObject 列表,而在 JSON 中,您需要一个列表,其元素将 RestObject 的实例包装在另一个对象中。这不是您可以通过简单的 Jackson 注释获得的东西,您需要一个仅用于 JSON 序列化的自定义序列化程序。首先,获得所需的 XML 格式很简单:

class RestObject implements Serializable 
    private LocalDateTime timestamp;
    private String title;
    private String fullText;
    private Long id;
    private Double value;


@JsonRootName("restObjectList")
class RestObjectList 
    @JacksonXmlProperty(localName = "restObject")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<RestObject> restObjectList;

如果您绝对想将数组中的每个元素包装在 json 中,您将需要一个自定义序列化程序,例如

class RestObjectSerializer extends JsonSerializer<RestObject> 
    @Override
    public void serialize(RestObject value, JsonGenerator gen, SerializerProvider serializers) throws
            IOException 
        gen.writeStartObject();
        gen.writeObjectFieldStart("restObject");
        gen.writeObjectField("timeStamp", value.getTimestamp());
        gen.writeStringField("title", value.getTitle());
        // other fields
        gen.writeEndObject();
        gen.writeEndObject();
    

并且仅在序列化 JSON 的ObjectMapper 上注册,这样它就不会干扰序列化为 XML:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("MyModule");
module.addSerializer(RestObject.class, new RestObjectSerializer());
mapper.registerModule(module);

【讨论】:

以上是关于Jackson xml 和 json 根元素的主要内容,如果未能解决你的问题,请参考以下文章

解析xml的工具类 -----jackson

json序列化定义类型jsckson

Jackson 将列表序列化为 xml 和 json

Jackson 序列化:XML 和 JSON 的不同格式

Jmeter做接口测试JSON返回值乱码而且未格式化解决

Jackson 学习笔记 XML转JSON