2

I'm facing the following situation parsing a JSON. The JSON I want to unmarshal contains an array of numbers (doubles) like this:

"position":[52.50325,13.39062]

So there is no name/value pairs.

The Problem is that I can't get the value of this array. In the Java object modeling the JSON I defined the position attribute as list of Doubles: List<Double> but after the unmarshel, the position attribute is always null.

For testing purpose I changed the content of the JSON like that:

position: [„52.50325“ ,“ 13.39062“ ]

and then there is no issue, I get the list with two elements. (Btw, this happens regardless if the position is defined as list of Strings or list of Doubles (List<String> or List<Double>))

So a workaround could be to alter the JSON response and mark this numbers as string before unmarshaling it, but I would like to avoid that, and I’m wondering if there is solution to get the value of a number array?

Here is a snapshot from the code:

ResultsListDO.java:

@XmlElement(required = true)
protected List<Double> position;

public List<Double> getPosition()
{
  if (position == null) {
    position = new ArrayList<Double>();
  }

  return this.position;
}

JSON unmarshal:

context = new JSONJAXBContext(JSONConfiguration.mapped().build(), ResultsListDO.class);
JSONUnmarshaller um = context.createJSONUnmarshaller();
ResultsListDO resultsList = um.unmarshalFromJSON(source.getReader(), ResultsListDO.class);
  • It's weird that you have logic in your getter/setter in a data object. See http://stackoverflow.com/questions/7955319/getters-and-setters-performing-additional-logic – Joseph Helfert Aug 22 '13 at 13:34

1 Answers1

1

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

Unless you have annotated your class with @XmlAccessorType(XmlAccessType.FIELD) the problem is probably that your annotation is on the field rather than the get method (see: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html).

import java.util.*;
import javax.xml.bind.annotation.XmlElement;

public class Foo {

    protected List<Double> position;

    @XmlElement(required = true)
    public List<Double> getPosition()
    {
      if (position == null) {
        position = new ArrayList<Double>();
      }

      return this.position;
    }

}

Demo Code

Below I'll demonstrate that everything works using MOXy as the JSON-binding provider.

jaxb.properties

To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Demo

import java.util.*;

import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String,Object>();
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource json = new StreamSource("src/forum18355753/input.json");
        Foo foo = unmarshaller.unmarshal(json, Foo.class).getValue();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(foo, System.out);
    }

}

input.json/Output

{
   "position" : [ 52.50325, 13.39062 ]
}
bdoughan
  • 147,609
  • 23
  • 300
  • 400