Home > front end >  Deserialize XML containing Properties and Values with Jackson
Deserialize XML containing Properties and Values with Jackson

Time:02-14

I'm trying to deserialize the following XML.

<RESPONSE>
    <FIELDS>
        <FIELD KEY="MSG_VERSION">003</FIELD>
        <FIELD KEY="CUSTOMER_NBR">001</FIELD>
        ...
        <FIELD KEY="ORIGINAL_TYPE">RM1</FIELD>
    </FIELDS>
</RESPONSE>

I need to capture the values from KEY properties and the values. Following is the Java class I have created.

package io.app.domain;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JacksonXmlRootElement(localName = "RESPONSE")
public class ResponseData {
    @JacksonXmlElementWrapper(localName = "FIELDS")
    @JacksonXmlProperty(localName = "FIELD")
    private List<Field> fields = new ArrayList<>();
    @Data
    public static class Field {
        @JacksonXmlProperty(isAttribute = true)
        private String key;
        @JacksonXmlText(value = true)
        private String content;
    }
}

The XmlMapper has been initialized as follows.

private final XmlMapper xmlMapper = new XmlMapper();

xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

The issue is that, although the content is properly getting set, the key value is always null. What am I doing wrong here?

CodePudding user response:

As @Thomas pointed out in a comment on the post, it was the case of the property that was causing the issue.

@JacksonXmlProperty(isAttribute = true, localName = "KEY")
private String key;

This was the fix.

CodePudding user response:

Or you can have like below. (I haven't tried)

@JacksonXmlRootElement(localName = "RESPONSE")
class ResponseFields {

    @JacksonXmlProperty(localName = "FIELDS")
    @JacksonXmlElementWrapper(useWrapping = false)
    private Fields[] fields;

    //getters, setters, toString
}


class Fields {
    @JacksonXmlProperty(localName = "FIELD")
    private Field field;

    //getters, setters, toString
}

class Field {
    @JacksonXmlProperty(isAttribute = true)
    private String key;
    @JacksonXmlText(value = true)
    private String value;

    //getters, setters, toString
}

And then;

XmlMapper mapper = new XmlMapper();
ResponseFields responseFields = mapper.readValue(XML, ResponseFields.class);
System.out.println(responseFields);
  • Related