开发者

JAXB / Jackson handling arrays

I'm currently writing a Jersey REST interface for a web application. What I want is the ability to be able to serialize a JSON and XML request to the same object however I'm having trouble getting the Jersey (i.e. JAXB / Jackson) to consume the XML and JSON in the format I want.

The XML structure looks like so:

<?xml version="1.0" encoding="UTF-8" ?>
<message>
  <buckets>
    <bucket>
      <channels>
         <channel>T开发者_开发知识库est A</channel>
         <channel>Test B</channel>
      </channels>
      <text>This is sample text</text>
    </bucket>
    <bucket>
      <channels>
        ....
      </channels>
      <text>This is sample text</text>
    </bucket>
  </buckets>
  <userId>10</userId>
 </message>

The class looks like:

@XmlRootElement(name="message")
public class MultiMessageRS {

    public static class Bucket {
        private List<String> channels;
        private String text;

        public Bucket () {}

        @XmlElementWrapper(name="channels")
        @XmlElement(name="channel")
        public List<String> getChannels() {
            return channels;
        }

        public void setChannels(List<String> channels) {
            this.channels = channels;
        }
        public String getText() {
            return text;
        }
        public void setText(String text) {
            this.text = text;
        }
    }

    private List<Bucket> buckets;

    private long userId;

    public MultiMessageRS () {}

    @XmlElementWrapper(name="buckets")
    @XmlElement(name="bucket")
    public List<Bucket> getBuckets() {
        return buckets;
    }
    public void setBuckets(List<Bucket> buckets) {
        this.buckets = buckets;
    }

    public long getUserId() {
        return userId;
    }
    public void setUserId(long userId) {
        this.userId = userId;
    }
}

This works fine for the XML however it's unable to consume the JSON in the format I would like. Namely, the issue is that it isn't picking up the channels array. The format is as follows:

{
   "buckets":[
      {
         "bucket":{
            "channels":[
               "twitter",
               "mobile"
            ],
            "text":"This is sample text"
         },
         "bucket":{
            "channels":[
               "email",
               "voice"
            ],
            "text":"This is sample text"
         }
      }
   ],
   "userId":"10"
}

From it to work correctly with the JSON, I would have to do something like adding a 'channel' array under 'channels' which is pretty dodgy. How will I be able to handle this situation?


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

EclipseLink JAXB (MOXy) offers native support for JSON-binding. Below is an example demonstrating the XML and JSON representation of the model you posted in your question.

Demo

package forum7735245;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(MultiMessageRS.class);

        File xml = new File("src/forum7735245/input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        MultiMessageRS message = (MultiMessageRS) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.setProperty("eclipselink.json.include-root", false);
        marshaller.marshal(message, System.out);
    }

}

input.xml

<?xml version="1.0" encoding="UTF-8" ?>
<message>
  <buckets>
    <bucket>
      <channels>
         <channel>Test A</channel>
         <channel>Test B</channel>
      </channels>
      <text>This is sample text</text>
    </bucket>
    <bucket>
      <channels>
        ....
      </channels>
      <text>This is sample text</text>
    </bucket>
  </buckets>
  <userId>10</userId>
 </message>

Output

{
   "buckets" : {
      "bucket" : [ {
         "channels" : {
            "channel" : [ "Test A", "Test B" ]
         },
         "text" : "This is sample text"
      }, {
         "channels" :  {},
         "text" : "This is sample text"
      } ]
   },
   "userId" : 10
}

For More Information

  • JSON Binding with EclipseLink MOXy - Twitter Example
  • MOXy as Your JAX-RS JSON Provider - Server Side


I think you are overcomplicating your JSON (as well as making it invalid by repeating same property name). It seems like what you might want to use is something like:

{
  "buckets":[
     {
        "channels":[
           "twitter",
           "mobile"
        ],
        "text":"This is sample text"
     }, {
        "channels":[
           "email",
           "voice"
        ],
        "text":"This is sample text"
     }
  ],
  "userId":"10"
}

which should work as expected.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜