Giter VIP home page Giter VIP logo

jackson-dataformat-xml's People

Contributors

ahcodedthat avatar arthurscchan avatar arturdryomov avatar bpasson avatar cowtowncoder avatar daannijkamp avatar dependabot[bot] avatar elexx avatar goooler avatar gtrog avatar joohyukkim avatar lkorth avatar mbladel avatar mensinda avatar migwel avatar naveensrinivasan avatar nurkiewicz avatar philzen avatar pjfanning avatar prb avatar ptziegler avatar simoncockx avatar simonetripodi avatar splatch avatar tamersaadeh avatar tatu-at-salesforce avatar timrs2998 avatar valery1707 avatar vmi avatar yawkat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jackson-dataformat-xml's Issues

@JacksonXmlElementWrapper Conflicting getter/setter definitions for property

Hi, I'm using latest release 2.0.1 and I've got a problem with serializing/deserializing xml (everything works fine in JSON).
I'd like to have such a xml: namename

public class WrapperTest {

public static void main(String[] args) throws JsonGenerationException,
        JsonMappingException, IOException {
    ObjectMapper mapper = new XmlMapper();
    Bean bean = new Bean();
    BeanInfo beanInfo = new BeanInfo();
    beanInfo.setName("name");
    BeanInfo beanOther = new BeanInfo();
    beanOther.setName("name");
    bean.setBeanInfo(new BeanInfo[] { beanInfo });
    bean.setBeanOther(new BeanInfo[] { beanOther });
    String output = mapper.writeValueAsString(bean);
    System.out.println(output);
}

@JacksonXmlRootElement(localName = "output")
private static class Bean {
    private BeanInfo[] beanInfo;
    private BeanInfo[] beanOther;

    @JacksonXmlElementWrapper(localName = "beanInfo")
    @JacksonXmlProperty(localName = "item")
    public BeanInfo[] getBeanInfo() {
        return beanInfo;
    }

    @JacksonXmlElementWrapper(localName = "beanInfo")
    public void setBeanInfo(BeanInfo[] beanInfo) {
        this.beanInfo = beanInfo;
    }

    @JacksonXmlElementWrapper(localName = "beanOther")
    @JacksonXmlProperty(localName = "item")
    public BeanInfo[] getBeanOther() {
        return beanOther;
    }
    @JacksonXmlElementWrapper(localName = "beanOther")
    public void setBeanOther(BeanInfo[] beanOther) {
        this.beanOther = beanOther;
    }
}

private static class BeanInfo {
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

}

This example give getter definition conflict.

If I change

@JacksonXmlElementWrapper(localName = "beanOther")
        @JacksonXmlProperty(localName = "item2")
        public BeanInfo[] getBeanOther() {
}

then all work fine and I've got

<output><beanInfo><item><name>name</name></item></beanInfo><beanOther><item2><name>name</name></item2></beanOther></output>

but if I try to deserialize it then I've got setter definition conflict...

XML Unwrapping no longer working for wrapped elements

Hi,

Using Jackson 2.1.1 when unwrapping a list from XML I no longer get each list item as an object but instead it returns the text attribute of each item. Here's a test case to show what I mean:

    static class Name {
        @JacksonXmlProperty(isAttribute=true)
        public String language

        @JacksonXmlText
        public String text

        public String data

        public Name(String data) {
            this.data = data;
        }
    }

    @XmlRootElement
    static class RoomName {
        @JacksonXmlElementWrapper(localName = "names", useWrapping=true)
        public List<Name> names

    }

    @Test
    void jacksonUnwrappingTest() {
        String xmlData = "<roomName>" +
                    "<names>" +
                        "<name language=\"en\">SPECIAL</name>" +
                    "</names>" +
                "</roomName>";

        RoomName roomName= null;

        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        roomName = xmlMapper.readValue(xmlData, RoomName.class);

        assert(roomName.names.get(0).data.equals("SPECIAL"));
    }

The assert is true when it shouldn't be. In jackson 2.0.6 that I was using previously this worked fine and returned:

<name language=\"en\">SPECIAL</name>

Which correctly mapped to the language and text (I didn't have the Name constructor before, that is only there for this test case).

How do I get linefeeds from my XML to deserialize into my strings in POJO

I have an XML with line feeds in it and when I use the XMLMapper, the line feeds are gone.
What do I have to do to get the line feeds to stay?

i.e.

my xml
...
<comment>Automatic move to
In Progress due to
a rejected drawing</comment>
...

My Java Code.

        XmlMapper mapper = new XmlMapper();
                    MyObj obj = mapper.readValue(xmlCode, MyObj.class)

// I want obj.comment to have the line feeds in it

Current master failing?

It seems like the current master is failing compilation. (I did manually delete all 1.8.0 files from my repository before posting this, just in case I had some old versions lying around.) Here's what I see:

cwinters@abita:#..jackson-xml-databind-orig$ rm -rf target
cwinters@abita:#..jackson-xml-databind-orig$ mvn install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Jackson-XML-databind
[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
Downloading: http://repo1.maven.org/maven2/org/codehaus/jackson/jackson-mapper-asl/1.8.0/jackson-mapper-asl-1.8.0.pom

Downloading: http://repo1.maven.org/maven2/org/codehaus/jackson/jackson-core-asl/1.8.0/jackson-core-asl-1.8.0.pom

Downloading: http://repo1.maven.org/maven2/org/codehaus/jackson/jackson-xc/1.8.0/jackson-xc-1.8.0.pom

Downloading: http://repo1.maven.org/maven2/org/codehaus/jackson/jackson-mapper-asl/1.8.0/jackson-mapper-asl-1.8.0.jar

Downloading: http://repo1.maven.org/maven2/org/codehaus/jackson/jackson-core-asl/1.8.0/jackson-core-asl-1.8.0.jar

Downloading: http://repo1.maven.org/maven2/org/codehaus/jackson/jackson-xc/1.8.0/jackson-xc-1.8.0.jar

[INFO] [enforcer:enforce {execution: enforce-maven}]
[INFO] [resources:resources {execution: default-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /opt/java/jackson/jackson-src/jackson-xml-databind-orig/src/main/resources
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 16 source files to /opt/java/jackson/jackson-src/jackson-xml-databind-orig/target/classes
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure

/opt/java/jackson/jackson-src/jackson-xml-databind-orig/src/main/java/com/fasterxml/jackson/xml/XmlTypeResolverBuilder.java:[142,12] cannot find symbol
symbol  : constructor ClassNameIdResolver(org.codehaus.jackson.type.JavaType)
location: class org.codehaus.jackson.map.jsontype.impl.ClassNameIdResolver

/opt/java/jackson/jackson-src/jackson-xml-databind-orig/src/main/java/com/fasterxml/jackson/xml/XmlTypeResolverBuilder.java:[163,12] cannot find symbol
symbol  : constructor MinimalClassNameIdResolver(org.codehaus.jackson.type.JavaType)
location: class org.codehaus.jackson.map.jsontype.impl.MinimalClassNameIdResolver

/opt/java/jackson/jackson-src/jackson-xml-databind-orig/src/main/java/com/fasterxml/jackson/xml/ser/XmlBeanSerializer.java:[81,4] method does not override or implement a method from a supertype

[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 24 seconds
[INFO] Finished at: Fri May 06 15:04:04 EDT 2011
[INFO] Final Memory: 25M/171M
[INFO] ------------------------------------------------------------------------

I tried some very naive fixes (passing in 'null' for the missing TypeFactory but failed.

Problem with DEFAULT_VIEW_INCLUSION and lists of objects

I have a pair of classes: Foo and Bar. Foo contains an array of Bar objects. When I turn off DEFAULT_VIEW_INCLUSION, my list of Bar objects isn't rendered at all when I make a XmlMapper.writeString() call, although it is rendered properly as JSON with a simple ObjectMapper.writeString(). Code below.

public class Views
{
    public static class RestrictedView { };
    public static class UnrestrictedView extends RestrictedView { };
}

public class Foo
{
    @JsonView( Views.RestrictedView.class )
    @JsonProperty
    private String restrictedFooProperty;
    @JsonView( Views.UnrestrictedView.class )
    @JsonProperty
    private String unrestrictedFooProperty;
    @JsonView( Views.RestrictedView.class )
    @JsonProperty
    private Bar[] bars;
    ...
}

public class Bar
{
    @JsonView( Views.RestrictedView.class )
    @JsonProperty
    private int restrictedBarProperty;
    @JsonView( Views.UnrestrictedView.class )
    @JsonProperty
    private int unrestrictedBarProperty;
    ...
}

And my test:

    Foo foo = new Foo();
    foo.setRestrictedFooProperty( "test" );

    Bar bar1 = new Bar();
    bar1.setRestrictedBarProperty( 10 );
    bar1.setUnrestrictedBarProperty( 1 );

    Bar bar2 = new Bar();
    bar2.setRestrictedBarProperty( 11 );
    bar2.setUnrestrictedBarProperty( 2 );

    Bar[] bars = new Bar[] { bar1, bar2 };
    foo.setBars( bars );

    ObjectMapper jsonMapper = new ObjectMapper();
    ObjectMapper xmlMapper = new XmlMapper();

    jsonMapper.configure( SerializationConfig.Feature.AUTO_DETECT_FIELDS, false );
    jsonMapper.configure( SerializationConfig.Feature.AUTO_DETECT_GETTERS, false );
    jsonMapper.configure( SerializationConfig.Feature.AUTO_DETECT_IS_GETTERS,  false );
    jsonMapper.configure( SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false );

    xmlMapper.configure( SerializationConfig.Feature.AUTO_DETECT_FIELDS, false );
    xmlMapper.configure( SerializationConfig.Feature.AUTO_DETECT_GETTERS, false );
    xmlMapper.configure( SerializationConfig.Feature.AUTO_DETECT_IS_GETTERS, false );
    xmlMapper.configure( SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false );

    String json = jsonMapper.viewWriter( Views.RestrictedView.class ).writeValueAsString( foo );
    String xml = xmlMapper.viewWriter( Views.RestrictedView.class ).writeValueAsString( foo );

    System.out.println( "JSON: \n" + json + "\n" );
    System.out.println(" XML: \n" + xml + "\n" );

And output:

 [java] JSON: 
 [java] {"restrictedFooProperty":"test","bars":[{"restrictedBarProperty":10}, {"restrictedBarProperty":11}]}
 [java] 
 [java]  XML: 
 [java] <Foo><restrictedFooProperty>test</restrictedFooProperty></Foo>

Unrecognized field "" when parsing attribute value

I got an exception from a basic xml structure.

Exception in thread "main"
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "" (class com.test.stack.Slot), not marked as
ignorable (4 known properties: , "id", "name", "width", "height"])

at [Source: resources\buildFile; line: 41, column: 192](through reference chain: .....)

at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)

at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:568)

Here the interesting part

....
<com.test.stack name="stack1">
<com.test.stack.slot height="0" id="0" name="slot0" width="0">+/null/this is a long string</com.test.stack.slot>
</com.test.stack>

public class Stack {

public String name;

@JsonProperty("com.test.stack.slot")
public Slot slot;

}

//@JsonIgnoreProperties(ignoreUnknown = true) //Need to have that I'll get an exception
public class PieceSlot {
public String name;
public String id;
public String height;
public String width;

}

At this point, I didn't figure out yet how to retreive the value for "Slot" object.

unnecessary xmlns="" in the root element

ObjectMapper xmlMapper = new XmlMapper();
String xml = xmlMapper.writeValueAsString(new Simple());

and with POJO like:

public class Simple {
public int x = 1;
public int y = 2;
}

you would get something like:

<Simple xmlns="">
  <x>1</x>
  <y>2</y>
</Simple>

There is a xmlns="" attribute at the root element, which was not expected.
Using version 2.0.4 (dataformat-xml) with 2.0.5 (core)

XmlMapper parse &<> Instead of the expected

i want to parse map to xml string

lib:
jackson-annotations-2.0.2.jar
jackson-core-2.0.2.jar
jackson-databind-2.0.2.jar
jackson-dataformat-xml-2.0.2.jar
stax2-api-3.1.1.jar

code:
public static void main(String[] args) throws Exception {
XmlMapper mapper = new XmlMapper();
Map xx = new HashMap();
xx.put("asd", "asd ##&## xx");
String xxx = mapper.writeValueAsString(xx);
System.out.println(xxx);
}

this map parse to xml i want: asd ##&##xx

but the actual: asd ##&## xx&asd ##&##xx

Incorrectly parsing XML with duplicated tag names

Trying to parse the following XML document:

<data>
  <r><a>A</a></r>
  <r><b>B</b><c>C</c></r>
</data>

with:

new XmlMapper().readValue(xml, Map.class)

ignores the first "r" (r -> {a -> A}) node, overriding it with a second one (r -> {b -> B, c -> C}). It should generate a map with a single key and array value instead: r -> [{a -> A}, {b -> B, c -> C}]. The problem is here (last line of org.codehaus.jackson.map.deser.MapDeserializer#_readAndBind):

            /* !!! 23-Dec-2008, tatu: should there be an option to verify
             *   that there are no duplicate field names? (and/or what
             *   to do, keep-first or keep-last)
             */
            result.put(key, value);

Although this can be worked around by using special map implementation instead of Map.class, but if the duplicated tags appear deeper in XML document (not at top level), there is no easy workaround, see org.codehaus.jackson.map.deser.UntypedObjectDeserializer#mapObject class (LinkedHashMap creation).

Of course the root cause of this problem is the assumption that there are no duplicate properties in JSON. In XML such nodes should be treated as arrays.

Make XML text use virtual name of property annotated with @JacksonXmlText

Currently all CDATA segments use bogus name of "" (empty String), and this works when binding to String type. But there are JAXB use cases where text is bind to actual property.
To support this use case, we should probably use name of property to expose CDATA instead, if at all possible.

Alternatively, if not possible, maybe we should just add a feature to allow changing name used; since JAXB defaults to "value", this should be the usual override to use.

`ACCEPT_EMPTY_STRING_AS_NULL_OBJECT` not honored in xml module for attributes

I'm having some issues with the treatment of empty strings in the XML module.

Say I have this:

class A {
 @JacksonXmlProperty( isAttribute = true )
 private String stringA;
 private String stringB;
}

A a = new A();
a.setStringA("");
a.setStringB("");

In JSON this would give me:

{ "stringA": "", "stringB": ""}

In XML this gives me:

<A stringA="">
 <stringB />
</A>

Which means that the attribute is treated correctly (as according to
the defaults), but for the element, it shows up as null. And is
therefore deserialized back as a null string.

@JacksonXmlText Unrecognized field "" when parsing attribute value

here the test case : https://gist.github.com/2351109

I downloaded the trunk and run my unit test. Here the result

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "" (class com.test.stack.Slot), not marked as ignorable (5 known properties: , "value", "width", "height", "name", "id"])
at [Source: resources\emptyField.xml; line: 4, column: 115](through reference chain: com.test.stack.Main["com.test.stack"]->com.test.stack.Stack["com.test.stack.slot"]->com.test.stack.Slot[""])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)
at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:568)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:649)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:830)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:310)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:338)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:87)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:290)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:338)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:87)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:290)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2563)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1759)
at com.test.stack.TestImporter.main(TestImporter.java:21)

ToXmlGenerator startWrappedValue / finishWrappedValue bypass pretty printer

startWrappedValue and finishWrappedValue both bypass pretty printer, so that wrapped values are badly written :

<previousField>
   ...
</previousField><wrapper>
   ...
   <wrapped>
      ...
   </wrapped></wrapper>
<nextField>

Pretty representation should be :

<previousField>
   ...
</previousField>
<wrapper>
   ...
   <wrapped>
      ...
   </wrapped>
</wrapper>
<nextField>

Binary data does not get reset with deserialising from XML

Related jackson-dataformat-xml version 2.0.4

While reading more than one data into byte[] we see that we always get the value of first data deserialised.
This happens only with xml deserialisation and not with json deserialisation.
It seems as if the _binaryValue does not get reset, as for example it is done in com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken()

See test case below, where xmlReadTwoData fails while jsonReadTwoData succeeds.

import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import java.io.IOException; import org.apache.commons.codec.binary.Base64; import org.junit.Test; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class XmlToMultipleByteTest{

public static class Data {

    @JsonProperty
    byte[] bytes;
}

public static class TwoData {
    @JsonProperty
    Data data1;

    @JsonProperty
    Data data2;
}

@Test
public void xmlReadTwoData() throws JsonParseException, JsonMappingException, IOException {
    String xml = 
        "<TwoData>" +
                "<data1><bytes>" + Base64.encodeBase64String("Hello".getBytes()) + "</bytes></data1>" +
                "<data2><bytes>" + Base64.encodeBase64String("World".getBytes()) + "</bytes></data2>" +
        "</TwoData>";

    TwoData two = new XmlMapper().readValue(xml, TwoData.class);
    assertThat( new String(two.data1.bytes), is("Hello"));
    assertThat( new String(two.data2.bytes), is("World"));
}

@Test
public void jsonReadTwoData() throws JsonParseException, JsonMappingException, IOException {
    String xml = 
        "{" +
            "\"data1\":{\"bytes\":\"" + Base64.encodeBase64String("Hello".getBytes()) + "\"}," +
            "\"data2\":{\"bytes\":\"" + Base64.encodeBase64String("World".getBytes()) + "\"}" +
        "}";

    TwoData two = new ObjectMapper().readValue(xml, TwoData.class);
    assertThat( new String(two.data1.bytes), is("Hello"));
    assertThat( new String(two.data2.bytes), is("World"));
}

}

Unable to find constructor for element key/value style.

I have a xml (trimed for this question)

<?xml version="1.0" encoding="UTF-8"?>
 <main>
  <com.test.options>
   <option name="icon1">/image1.png</option>
   <option name="icon2">/image2.png</option>
  </com.test.options>
</main>

I used this code :

ObjectMapper xmlMapper = new XmlMapper();
xmlMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

...

public class Main {

  @JsonProperty("com.test.Options")
  public Options options;
}

public class Options {
  public List<option> option;
}

public class Option {
  public String name;
  public String value;
}

So far, I never been able to find a solution to get rid of this exception

Exception in thread "main"
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.test.Option]: can not instantiate from JSON object (need to add/enable type information?)
...
com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:163)

I try to replace List by this :

public List option = new ArrayList();

but now, I get that :

Exception in thread "main"
com.fasterxml.jackson.databind.JsonMappingException: (was
java.lang.NullPointerException) (through reference chain: .....) at
com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:218)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:183)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:938)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:292)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:338)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:87)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:290)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2563)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1759)</option>

Respect field order during serialisation.

In order to match existing files from a human perspective, it'd be helpful if the order of elements matched the field order in the classes involved. Either that or provide some other way to choose the ordering, though that seems simplest.

Support root level collection serialization

I have done some tests with 2.1.0-SNAPSHOT since on RESThub project (https://github.com/resthub/resthub-spring-stack) we are waiting XML serialization of unwrapped lists for a while.

We use generic SpringMVC controller with Jackson 2.x for serialization.

@RequestMapping(method = RequestMethod.GET, params="page=no")
@responsebody
public List findAllNotPaginated() {
return (List)repository.findAll();
}

For JSON we get this normal output :

[{"id":17,"name":"toto"},{"id":18,"name":"toto"}]

For XML we get this bogus output (the same than is 2.0 I think) :

<ArrayList xmlns=""><id>41</id><name>toto</name></ArrayList><zdef1166645736:ArrayList xmlns:zdef1166645736=""><zdef1166645736:id>42</zdef1166645736:id><zdef1166645736:name>toto</zdef1166645736:name></zdef1166645736:ArrayList>

Is there something to do in order to activate Jackson 2.1 XML unwrapped list support, or is it a bug ?

Support for providing namespace to use for fields of a Class (unless overridden by field)

Currently in the xml-module you have to qualify each field with the wanted namespace. This in many ways are similar to JAXB, but JAXB provides @XmlSchema for adding namespaces at the package level.

It would be nice if one could provide a default namespace for a class, so that theres not need to qualify every single field.

Even better would be to provide this at the package level, but class level should be more than ok for now.

Problem with Enums, `@JsonTypeInfo` (and indirectly, `As.WRAPPER_ARRAY`)

(from Jackson user forum by Rich M)

Hi all. I am using jackson 1.7.1 and xml-databind 0.5.3, and ran into a minor issue. I have an attribute of type Object, which is unavoidable because its value can be a primitive or an Enum. I have tagged the attribute with @JsonTypeInfo. Everything works fine in JSON, however, the xml is erroneous when working with an Enum:

public class MyClass {  
    @JsonTypeInfo(use=JsonTypeInfo.Id.MINIMAL_CLASS, include=JsonTypeInfo.As.PROPERTY, property="__type")
    public Object value;
}

The JSON fragment for an Enum is:

"value" : [ "PersonBloodTypeCode", "ABMNUS" ]

The XML fragment does not nest properly. It looks like:

<value>PersonBloodTypeCode</value>
 <value>ABMNUS</value>

Which, when deserialized, results in a String instance "ABMNUS", rather than an enum.

Add @JacksonXmlText annotation

XML allows one kind of structure that JSON does not, namely things like:

<element attr="xyz" attr2="abc">text</element>

which could ideally match a POJO like:

public class Element {
  public String attr, attr;
  public String text;

}

The problem here is that the only way to indicate that a value should be serialized to / deserialized from a String is @JsonValue.
But its use requires that annotated property is the only property to use. This makes sense for JSON, but with XML, limit can be loosened.

Since we can not change global semantics (as this would not work too well with JSON), we need to introduce a new annotation; such as @JacksonXmlText. It would indicate that:

  • Value of annotated property should be serialized as simple String in XML (and deserialized from String)
  • POJO can have other properties, but they all MUST be serialized as attributes

Limitation on other properties is required because allowing elements would lead to mixed content model, which is something we can not handle. This is also limitation that JAXB has.
It is worth noting that this annotation would be very similar to JAXB @XmlValue, and we should try to then support that annotation as well (as an alias)

Deserializing when using custom wrapper element

I'm having some issues deserializing a class that uses a @JacksonXmlElementWrapper.

This how my class looks:

@JacksonXmlRootElement( localName = "person", namespace ="http://example.org/person" )
public class Person
{
   @JacksonXmlProperty( isAttribute = true )
   private String id;

   private String name;

   private Integer age;

   @JacksonXmlElementWrapper(localName = "notes")
   @JacksonXmlProperty( localName = "note" )
   private List<String> notes = new ArrayList<String>();

  // getters, setters, etc
}

And this gets serialized fine with:

Person p = new Person( "Name", 30 );
p.getNotes().add( "This is note #1" );
p.getNotes().add( "This is note #2" );

ObjectMapper xmlMapper = new XmlMapper();
String xml = xmlMapper.writeValueAsString( p );

This gives me something like:

<zdef-1759520061:person xmlns=""
xmlns:zdef-1759520061="http://example.org/person"
id="af47ac8e-ee8c-4e43-a87c-dbff93f28d87">
 <name>Name</name>
 <age>30</age>
 <notes>
   <note>This is note #1</note>
   <note>This is note #2</note>
 </notes>
</zdef-1759520061:person>

But, when I now try and deserialize this using:

Person p = xmlMapper.readValue( xml, Person.class );

I get:

Exception in thread "main"
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "notes" (Class Person), not marked as ignorable
 at [Source: java.io.StringReader@5c1fe88d; line: 1, column: 169]
(through reference chain: Person["notes"])
       at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)
       at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:526)
       at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:651)
       at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:771)
       at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:291)
       at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:99)
       at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2532)
       at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1774)

For 2.1, should support 'firstAsId' for Object Id handling

With Jackson 2.1, it will be possible to support "first-as-id" handling for Object Ids, with 'firstAsId' property of @JsonIdentityInfo.
But JAXB equivalent does not have such option, so we need to decide what should constitute defaults for this behavior.

Since JAXB seems to default to that behavior (as opposed to Jackson that does not), we could consider two ways to tackle this:

  1. Make JAXB annotation introspector indicate that 'firstAsId' is always set, when we find JAXB annotations
  2. Add a feature in XmlMapper, to override setting.

I am not 100% sure which way to go, at this point... but one or both should be done for Jackson 2.1

Support non-wrapped array serialization

Currently only "wrapped" arrays / collections are supported (meaning there is an element for array, and then one for each entry); but not "unwrapped" mode (only entries have xml element, not array itself). Since latter is the default for JAXB, it would be nice to support it.

JsonFilter with XmlMapper ignores xml attributes

Hello, I have the case where I want to use a JsonFilter to exclude a property from being serialized to xml. Everything is ok when all the properties of the bean are to be serialized as xml child elements.
However, when there exists a bean property that needs to be serialised as attribute, then the "isAttribute" annotation gets ignored.

Please find a test case below.

Thank you in advance for your help.

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import java.io.IOException;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

public class JsonFilterWithXmlAttributeTest {

    @JsonFilter("test-filter")
    @JsonPropertyOrder({ "id", "name"})
    abstract class TestFilterMixin{}

    @JsonPropertyOrder({ "id", "name", "jsonProp" })
    abstract class TestNoFilterMixin{}

    @JsonIgnoreProperties(ignoreUnknown=true)
    static class TestCls{

        private String id;
        private String name;
        private String jsonProp;

        public TestCls(){}

        public TestCls( String id, String name, String jsonProp ){
            this.id= id;
            this.name = name;
            this.jsonProp = jsonProp;
        }

        @JacksonXmlProperty(isAttribute=true)
        public String getId() {return id;}
        public void setId(String id) {this.id = id;}

        @JsonProperty("name")
        public String getName() {return name;}
        public void setName(String name) {this.name = name;}

        @JsonProperty("jsonProp")
        public String getJsonProp() {return jsonProp;}
        public void setJsonProp(String jsonProp) {this.jsonProp = jsonProp;}    

    }

    @Test
    public void testFilter() throws JsonGenerationException, JsonMappingException, IOException{
        XmlMapper mapper = new XmlMapper();

        mapper.addMixInAnnotations( TestCls.class, TestFilterMixin.class);

        FilterProvider filters = new SimpleFilterProvider().addFilter("test-filter",
                SimpleBeanPropertyFilter.serializeAllExcept("jsonProp"));
        mapper.setFilters(filters);

        TestCls test = new TestCls( "123", "tester", "jsonText");

        String xml = mapper.writeValueAsString(test);

        assertThat("xml", xml, is("<TestCls id=\"123\"><name>tester</name></TestCls>") );

    }

    @Test
    public void testNoFilter() throws JsonGenerationException, JsonMappingException, IOException{
        XmlMapper mapper = new XmlMapper();

        mapper.addMixInAnnotations( TestCls.class, TestNoFilterMixin.class);

        TestCls test = new TestCls( "123", "tester", "jsonText");

        String xml = mapper.writeValueAsString(test);

        assertThat("xml", xml, is("<TestCls id=\"123\"><name>tester</name><jsonProp>jsonText</jsonProp></TestCls>") );

    }
}

Differences between ObjectMapper and XmlMapper when using custom serializer

I have a problem when trying to deserialize string produced by XmlMapper.
Simple Item and Foo class:

public class Item {
  public String name;
  public Foo obj;
  public Item(String name, Foo obj) {
    this.name = name;
    this.obj = obj;
  }
}

public class Foo {
  public String name;
  public Foo(String name) {
    this.name = name;
  }
}

My serializer looks as following:

public class ItemSerializer extends StdSerializer<Item> {
  public ItemSerializer() {
    super(Item.class);
  }

  public void serialize(Item value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
    jgen.writeStartObject();
    jgen.writeObjectField("obj", value.obj);
    jgen.writeStringField("name", value.name);
    jgen.writeEndObject();
  }
}

Deserializer:

public class ItemDeserializer extends StdDeserializer<Item> {
  public ItemDeserializer() {
    super(Item.class);
  }

  public Item deserialize(JsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    ObjectCodec oc = jp.getCodec();
    JsonNode json = oc.readTree(jp);
    // other code
  }
}

Test:


public class Test {
  public static void main(String[] args) {
    ObjectMapper json = new ObjectMapper();
    XmlMapper xml = new XmlMapper();
    SimpleModule m = new SimpleModule("module", new Version(1,0,0,null,null,null));
    m.addSerializer(Item.class, new ItemSerializer());
    m.addDeserializer(Item.class, new ItemDeserializer());
    json.registerModule(m);
    xml.registerModule(m);

    Item value = new Item("itemName", new Foo("fooName"));
    String a = json.writeValueAsString(value);
    String b = xml.writeValueAsString(value);

    Item x = json.readValue(a, Item.class);
    Item y = xml.readValue(b, Item.class);
  }
}

Second deserialization (y variable) fails. The problem is in deserializer at last shown line: variable json has different values for XmlMapper and for ObjectMapper.

  1. value with ObjectMapper:
{"obj":{"name":"fooName"},"name":"testName"}
  1. value with XmlMapper:
{"Foo":{"name":"fooName"},"name":"testName"}

Shouldn't these two be same? Now my deserializer works only for json, not for xml.

Bad empty element with attribute representation with DefaultXmlPrettyPrinter

In version 2.0.4, empty element with zero, one or more attributes are written :

<element>
</element>

or

<element attribute="xxx">
</element>

It may be better to write :

<element />
<element attribute="xxx" />

With some investigation, I notice that empty / non empty switch is based on nrOfEntries in writeEndObject and that non empty element is always choosen.

I don't understand the real nrOfEntries purpose, but it should not be used for empty / non empty switch.

I implement my own PrettyPrinter, subclass of DefaultXmlPrettyPrinter and I switch between empty / non empty based on a boolean stack and it works.
I modify the boolean when pretty printer methods are called :

  • writeStartObject, writeStartArray : add a new FALSE boolean on the stack (FALSE because empty)
  • writeEndObject : remove an boolean element of the stack
  • writeLeaf* : replace last element of the stack with TRUE (TRUE because non empty)

Here is a link of my PrettyPrinter version : http://pastebin.com/UaTujcce

Unable to deserialize String from list items

I'm trying to deserialize this xml with jackson-dataformat-xml 2.0...

<com.test.players>
  <entry>Player 1</entry>
  <entry>Player 2</entry>
</com.test.players>

into this classes:

public class Main {
  @JsonProperty("com.test.Players")
  public Players players;
}

public class Players {
  public List<string> entry;
}

I look into the source code and it look like Jackson xml-bind doesn't like when the List are String.

I have to put this feature ON, if I want the code to run.

ObjectMapper xmlMapper = new XmlMapper();
xmlMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

if I don't do that.. it will give the exception below

Exception in thread "main"
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize
instance of java.util.ArrayList out of VALUE_STRING token

If I use the feature at ON.. the code will works.. BUT the List entry, will contains onyl the last value of the list.

Anyone have a idea to fix that ?

Maybe I could put the entry's values into a object Entry with a String constructor ? (no idea how to do do, if it's possible)

Can't parse more than one XML attribute

XmlMapper parses only the first XML attribute, ignoring subsequent ones if any. In the following XML code snippet only "max" attribute is deserialized:

<data max="7" offset="9" total="11"/>

I found and fixed the bug already:

nurkiewicz@9b51833

newbie questions about customizing XmlMapper

Greetings. I'm excited about using jackson to serialize xml as well as json. I've got an existing object model that currently uses jackson/json. I have a requirement to produce/consume xml from services that can't handle json.

A few newbie questions around tweaking the output.
I've looked at com.fasterxml.jackson.databind.SerializationConfig etc. but have been unable to unlock the tricks

testFooToXML() Produces

<Foo><i>1</i><f>1.1</f><d>1330459205157</d><s>s</s><n/></Foo>

How to suppress nulls ?
How to render date as iso 8601?

testArrayFooToXML() Produces

<Foo[]><i>1</i><f>1.1</f><d>1330459775907</d><s>s</s><n/></Foo[]>

Foo[] is illegal xml name?

public class TestSerialization {

@Test
public void testFooToXML() throws Exception  {
    ObjectMapper xmlMapper = new XmlMapper();
    Foo f = new Foo();
    String xml = xmlMapper.writeValueAsString(f);
    System.err.println(xml) ;
}
@Test
public void testArrayFooToXML() throws Exception  {
    ObjectMapper xmlMapper = new XmlMapper();
    Foo[] foos = new Foo[]{ new Foo() };
    String xml = xmlMapper.writeValueAsString(foos);
    System.err.println(xml) ;
} 

public class Foo {
    int i = 1 ;
    float f = 1.1f ;
    Date d = new Date() ;
    String s = "s" ;
    String n = null ;
    public Foo() {
        super();
    }
    public int getI() {
        return i;
    }
    public void setI(int i) {
        this.i = i;
    }
    public float getF() {
        return f;
    }
    public void setF(float f) {
        this.f = f;
    }
    public Date getD() {
        return d;
    }
    public void setD(Date d) {
        this.d = d;
    }
    public String getS() {
        return s;
    }
    public void setS(String s) {
        this.s = s;
    }
    public String getN() {
        return n;
    }
    public void setN(String n) {
        this.n = n;
    }

}

}

Custom @XmlJavaTypeAdapter ignored when applied to Map

We need() a XmlAdapter because the XML element name will use the map key (containing invalid characters(*))

@XmlJavaTypeAdapter(URLEncoderMapDataAdapter.class)
Map<String,String> map;
...

map.put("my/key","myvalue")
<my/key>my/value</my/key>)

() it's not a good idea to use schema-free attributes in a DTO, and JAXB solution looks ad-hoc and i'm not sure someone will have some real use case
(
*) one can take care (encode) before setting an URL as key

This simple test shows two different errors for

@XmlJavaTypeAdapter(URLEncoderMapDataAdapter.class)

or

@XmlJavaTypeAdapter(value = URLEncoderMapDataAdapter.class, type = MapData.class)
package com.fasterxml.jackson.dataformat.xml.jaxb;

import static java.util.Collections.singletonMap;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.dataformat.xml.XmlAnnotationIntrospector;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.XmlTestBase;

/**
 * Tring to use a custom XmlJavaTypeAdapter in order to modify how Maps are serialized
 */
public class TestXmlJavaTypeAdapter extends XmlTestBase
{
    /*
    /**********************************************************************
    /* Helper types
    /**********************************************************************
     */

    @XmlJavaTypeAdapter(URLEncoderMapDataAdapter.class)
    public static class MapData
    {
        public String key;

        public String value;

        public MapData()
        {

        }

        public MapData(String key, String value)
        {
            super();
            this.key = key;
            this.value = value;
        }
    }

    public static class URLEncoderMapDataAdapter extends XmlAdapter<MapData[], Map<String, String>>
    {
        public URLEncoderMapDataAdapter()
        {

        }

        public MapData[] marshal(Map<String, String> arg0) throws Exception
        {
            MapData[] mapElements = new MapData[arg0.size()];
            int i = 0;
            for (Map.Entry<String, String> entry : arg0.entrySet())
            {
                mapElements[i++] = new MapData(encodeKey(entry.getKey()), entry.getValue());
            }

            return mapElements;
        }

        public Map<String, String> unmarshal(MapData[] arg0) throws Exception
        {
            Map<String, String> r = new HashMap<String, String>();
            for (MapData mapelement : arg0)
            {
                r.put(decodeKey(mapelement.key), mapelement.value);
            }
            return r;
        }

        private final static String ENCODING = "UTF-8";

        private String encodeKey(String key) throws UnsupportedEncodingException
        {
            return URLEncoder.encode(key, ENCODING);
        }

        private String decodeKey(String key) throws UnsupportedEncodingException
        {
            return URLDecoder.decode(key, ENCODING);
        }
    }

    @XmlRootElement(name = "DocWithMapData")
    public static class DocWithMapData
    {
        @XmlJavaTypeAdapter(value = URLEncoderMapDataAdapter.class, type = MapData.class)
        public Map<String, String> mapDatas;
    }

    @XmlRootElement(name = "DocWithMapDataSimpleAnnotation")
    public static class DocWithMapDataSimpleAnnotation
    {
        @XmlJavaTypeAdapter(URLEncoderMapDataAdapter.class)
        public Map<String, String> mapDatas;
    }

    private Map<String, String> simpleMapData = singletonMap("key", "value");

    private Map<String, String> needEncodingMapData = singletonMap("my/key", "my/value");

    /*
     * /********************************************************************** /* Set up
     * /**********************************************************************
     */

    protected XmlMapper _jaxbMapper;

    protected XmlMapper _nonJaxbMapper;

    @Override
    public void setUp() throws Exception
    {
        super.setUp();
        _jaxbMapper = new XmlMapper();
        _nonJaxbMapper = new XmlMapper();
        // Use JAXB-then-Jackson annotation introspector
        AnnotationIntrospector intr =
            XmlAnnotationIntrospector.Pair.instance(new XmlJaxbAnnotationIntrospector(),
                new JacksonAnnotationIntrospector());
        _jaxbMapper.setAnnotationIntrospector(intr);
    }

    /*
     * /********************************************************************** /* Unit tests
     * /**********************************************************************
     */

    public void testSimpleKeyMap() throws Exception
    {
        DocWithMapData bean = new DocWithMapData();
        bean.mapDatas = simpleMapData;

        assertEquals("<DocWithMapData><mapDatas><key>value</key></mapDatas></DocWithMapData>",
            _jaxbMapper.writeValueAsString(bean));
    }

    public void testNeedEncodingKeyMap() throws Exception
    {
        DocWithMapData bean = new DocWithMapData();
        bean.mapDatas = needEncodingMapData;

        assertEquals(
            "<DocWithMapData><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapData>",
            _jaxbMapper.writeValueAsString(bean));
    }

    public void testSimpleKeyMapSimpleAnnotation() throws Exception
    {
        DocWithMapDataSimpleAnnotation bean = new DocWithMapDataSimpleAnnotation();
        bean.mapDatas = simpleMapData;

        assertEquals(
            "<DocWithMapDataSimpleAnnotation><mapDatas><key>value</key></mapDatas></DocWithMapDataSimpleAnnotation>",
            _jaxbMapper.writeValueAsString(bean));
    }

    public void testNeedEncodingKeyMapSimpleAnnotation() throws Exception
    {
        DocWithMapDataSimpleAnnotation bean = new DocWithMapDataSimpleAnnotation();
        bean.mapDatas = needEncodingMapData;

        assertEquals(
            "<DocWithMapDataSimpleAnnotation><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapDataSimpleAnnotation>",
            _jaxbMapper.writeValueAsString(bean));
    }

    public void testNeedEncodingKeyMap_nonJaxb() throws Exception
    {
        DocWithMapData bean = new DocWithMapData();
        bean.mapDatas = needEncodingMapData;

        assertEquals(
            "<DocWithMapData><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapData>",
            _nonJaxbMapper.writeValueAsString(bean));
    }

    public void testNeedEncodingKeyMapSimpleAnnotation_nonJaxb() throws Exception
    {
        DocWithMapDataSimpleAnnotation bean = new DocWithMapDataSimpleAnnotation();
        bean.mapDatas = needEncodingMapData;

        assertEquals(
            "<DocWithMapDataSimpleAnnotation><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapDataSimpleAnnotation>",
            _nonJaxbMapper.writeValueAsString(bean));
    }
}

How to gracefully handle non-Stax2 problem with indentation (writeRaw)

Since non-Stax2 implementations like SJSXP2 can not implement writeRaw properly, and since indentation requires that, we have a problem where indentation will crash on SJSXP.

Instead of this, one of two things shoiuld happen:

  1. Indentation is simply omitted, when it can't be made to work, or
  2. Exception is thrown once this problem is detected; and exception specifically explaining the issue.

Support JAX-RS provider

It'd be great to be able to just plug in Jackson XML databind as the default JAX-RS XML provider.
It is possible that standard Jackson provider could work; however, we need to verify this is the case.
Also, if not (or if re-config or sub-classing is needed), we could still add separate provider to use with XML.

(thanks to james strachan for suggesting this!)

Add Support for joda date time serialiazation/deserialization in xml

jackson-datatype-joda provides excellent support for converting joda's types in json ser/deser. However, JodaModule only supports json. Adding JodaModule to XmlMapper produces the following output:

    <effectiveDate>2013</effectiveDate>
    <effectiveDate>1</effectiveDate>
    <effectiveDate>1</effectiveDate>

instead of something like: <effectiveDate year="2013" month="1" day ="1' />

What's the best way to implement this as a joda ser/deser module for xml?

Add equivalent of JAXB @XmlRootElement to specify name of root XML element

(note: re-creation of [http://jira.codehaus.org/browse/JACKSON-452] by Chris Winters)

JAXB allows you to override the name of the root element (using @XmlRootElement when generating XML. For example, rendering this class to XML:

@JsonIgnoreProperties( {"meal", "notMeal", "mealNameDisplay"} )
public class MealEvent...

Generates XML like this:

lunch ...

But I'd like the root element to be 'meal' instead of 'MealEvent'.

FWIW, I tried the wild guess using @JsonTypeName( "meal" ) as well – it had no effect.

In this discussion Tatu suggested the annotation @JacksonXmlRootName.

Provide or expose pretty-printing option(s)

If this exists, forgive me. I tried a json method and it threw some exception (which I don't have handy right now), and didn't see any docs about it. If/when this exists, please ensure that tabs/spaces(and how many) are choosable, somehow. XStream which I've fallen back to uses 2 spaces, and I'd much prefer tabs.

Serialization of List incorrect if property declared as non-Collection (Object)

(as reported by Paweł Kowol on Jackson users list)


If a List (or other Collection) is value of a non-Collection property, like so:

public class Bean {
  public Object list;
}

it will not be serialized correctly. This is most likely due to special handling of Collection types, which is triggered based on declared type of property (since it must be added statically when constructing bean serializers). Will need to see if this can be improved.

First attribute of list ignored

The unit test below will reproduce the problem. The general problem is that when the XML is deserialized jackson skips the attributes in the first entry of a list. All subsequent entries have their attributes read, and using an element instead of an attribute will work, but the first item in the list has it's attributes ignored.

I tried stepping through the code a bit, and found that the JsonParser tokens seem to go straight from the "wrapper" field to the "a" field without ever stopping at the "id" field. I could be wrong about this though.


import java.io.StringReader;
import java.util.List;

import junit.framework.Assert;

import org.junit.Test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

public class TestParseMarketStat
{
    @Test
    public void testBrokenParser() throws Exception
    {
        String xml = "<response><wrapper><item id=\"1\"><a>x</a><b>y</b></item><item id=\"2\"><a>y</a><b>x</b></item></wrapper></response>";
        XmlMapper mapper = new XmlMapper();
        Response res = mapper.readValue(new StringReader(xml), Response.class);

        System.out.println(new ObjectMapper().writeValueAsString(res));
        Assert.assertNotNull(res.getItems().get(0).getId());
    }

    public static class Response
    {
        @JacksonXmlProperty(localName = "wrapper")
        List<Item> items;

        public List<Item> getItems()
        {
            return items;
        }

        public void setItems(List<Item> items)
        {
            this.items = items;
        }
    }

    public static class Item
    {
        protected String id;
        protected String a;
        protected String b;

        public String getId()
        {
            return id;
        }

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

        public String getA()
        {
            return a;
        }

        public void setA(String a)
        {
            this.a = a;
        }

        public String getB()
        {
            return b;
        }

        public void setB(String b)
        {
            this.b = b;
        }

    }
}

Annotations being ignored

Hi!

I'm experiencing some issues using dataformat-xml module.

I've successfully managed to get jackson-jaxrs-json-provider working, and was trying with jackson-jaxrs-xml-provider too. I've tried two stax-api implementations:

  • woodstox-4.1.1, with the following error when serializing a collection:
    XMLStreamException occurred when processing request: Trying to output second root, . Stacktrace follows:
  • sjsxp-1.0.1: with this, collections are properly serialized.

In both cases, any kind of XML annotations are ignored (i.e.: @JacksonXmlProperty( isAttribute = true ), @JacksonXmlRootElement and @JacksonXmlElementWrapper.

I've tried with jersey implementations of both json and xml providers (jackson 1.8 and jaxb) and annotations works fine for them.

I don't know if this is an issue or a problem with stax-api implementation; could you help me, please?

Thanks in advance

Strange behavior with namespace generation when using isAttribute = true

Given this class:

package test2;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement( localName = "namespaceTest", namespace = Namespace.NAMESPACE )
public class NamespaceTest
{
    private boolean booleanA;

    protected String uid;

    public NamespaceTest()
    {

    }

    @JsonProperty
    @JacksonXmlProperty( isAttribute = true )
    public String getUid()
    {
        return uid;
    }

    public void setUid( String uid )
    {
        this.uid = uid;
    }

    @JsonProperty
    @JacksonXmlProperty( namespace = Namespace.NAMESPACE )
    public boolean isBooleanA()
    {
        return booleanA;
    }

    public void setBooleanA( boolean booleanA )
    {
        this.booleanA = booleanA;
    }
}

And this test program:

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import test2.NamespaceTest;

import java.io.IOException;
import java.util.UUID;

public class Main2
{
    public static void main( String... args ) throws IOException
    {
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.configure( ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true );
        xmlMapper.configure( MapperFeature.AUTO_DETECT_CREATORS, false );
        xmlMapper.configure( MapperFeature.AUTO_DETECT_FIELDS, false );
        xmlMapper.configure( MapperFeature.AUTO_DETECT_GETTERS, false );
        xmlMapper.configure( MapperFeature.AUTO_DETECT_IS_GETTERS, false );
        xmlMapper.configure( MapperFeature.AUTO_DETECT_SETTERS, false );

        NamespaceTest namespaceTest = new NamespaceTest();
        namespaceTest.setUid( UUID.randomUUID().toString() );
        namespaceTest.setBooleanA( true );

        xmlMapper.writeValue( System.out, namespaceTest );
    }
}

The output from running is:

<?xml version='1.0' encoding='UTF-8'?>
<wstxns1:namespaceTest xmlns:wstxns1="http://www.example.org" wstxns1:uid="8e7d9686-95a3-4c46-aeed-c9c1738a4f3e">
  <booleanA>true</booleanA>
</wstxns1:namespaceTest>

Even though I did not add any namespace to the uid field.. notice also that booleanA does not have a namespace associated with it.

If I change this:

    @JsonProperty
    @JacksonXmlProperty( isAttribute = true )
    public String getUid()
    {
        return uid;
    }

To

    @JsonProperty
    @JacksonXmlProperty
    public String getUid()
    {
        return uid;
    }

Then it is no longer an attribute (of course) but it also removes the namespace.. which is fine, but it should also not have this namespace when using isAttribute = true.

Regards,
Morten

XmlMapper seems to ignore custom serializer

I tried to add custom serializer to my XmlMapper for XML serialization:

JacksonXmlModule module = new JacksonXmlModule();
module.addSerializer(Item.class, new ItemSerializer());
XmlMapper xml = new XmlMapper(module);

However, it seems like XmlMapper ignore my serializer and serialize code on its own.

I tried this same serializer with ObjectMapper for JSON serialization:

SimpleModule module = new SimpleModule("MyModule", new Version(1,0,0,null,null,null);
module.addSerializer(Item.class, new ItemSerializer());
ObjectMapper json = new ObjectMapper();
json.registerModule(module);

It works fine for JSON.

Empty field name when attribute in parent node

new XmlMapper().readValue(
    "<order><person lang=\"en\">John Smith</person></order>",
    Map.class);

produces the following map:

person -> [
    "lang" -> "en"
    "" -> "John Smith"
    ]

Empty key is somehow created. However, if the attribute is removed we will simply get:

person  -> "John Smith"

Namespaces alias should be removed when there is no need for it

SSIA

public class TestNamespaces
{
   @JacksonXmlRootElement( localName = "person", namespace =
"http://example.org/person" )
   static class Person
   {
       private String name;

       @JacksonXmlProperty( namespace = "http://example.org/person" )
       public String getName()
       {
           return name;
       }

       public void setName( String name )
       {
           this.name = name;
       }
   }

   public static void main( String... args ) throws IOException
   {
       Person person = new Person();
       person.setName( "hello" );

       XmlMapper xmlMapper = new XmlMapper();
       xmlMapper.writeValue( System.err, person );
   }
}

That simple code gives me:

<wstxns1:person xmlns:wstxns1="http://example.org/person">
  <wstxns1:name>hello</wstxns1:name>
</wstxns1:person>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.