JAXB / Jackson обрабатывает массивы - PullRequest
1 голос
/ 12 октября 2011

В настоящее время я пишу REST-интерфейс Jersey для веб-приложения.Мне нужна возможность сериализации запросов JSON и XML к одному и тому же объекту, однако у меня возникают проблемы с получением Джерси (то есть JAXB / Jackson) для использования XML и JSON в нужном мне формате.

Структура 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>

Класс выглядит следующим образом:

@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;
    }
}

Это прекрасно работает для XML, однако он не может использовать JSON в формате Iхотел бы.А именно, проблема в том, что он не собирает массив каналов.Формат выглядит следующим образом:

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

Для правильной работы с JSON мне нужно будет сделать что-то вроде добавления массива 'channel' в 'channel', что довольно хитро.Как я смогу справиться с этой ситуацией?

Ответы [ 2 ]

1 голос
/ 12 апреля 2012

Примечание: Я EclipseLink JAXB (MOXy) и являюсь членом JAXB 2 (JSR-222 ) экспертная группа.

EclipseLink JAXB (MOXy) предлагает встроенную поддержку JSON-привязки. Ниже приведен пример, демонстрирующий представление в XML и JSON модели, которую вы опубликовали в своем вопросе.

Демо

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>

выход

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

Для получения дополнительной информации

0 голосов
/ 12 октября 2011

Я думаю, что вы слишком усложняете свой JSON (а также делаете его недействительным, повторяя то же имя свойства).Похоже, что вы можете использовать что-то вроде:

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

, который должен работать как положено.

...