Есть ли поддержка Java для сериализации JSPON со ссылками? - PullRequest
2 голосов
/ 25 марта 2012

Я ищу сериализатор Java JSPON, который может обрабатывать ссылки в соответствии со спецификацией JSPON.

Есть ли какие-либо доступные для этого в настоящее время?Или есть ли способ изменить существующий сериализатор для обработки ссылок на объекты с помощью нотации $ ref?

Ответы [ 2 ]

0 голосов
/ 26 марта 2012

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

Если вас интересует подход привязки объекта к JSON, ниже показано, как это можно сделать с помощью MOXy.Приведенный ниже пример основан на примере из базовой спецификации JSPON:

Parent

Parent класс - это объект домена, который соответствует корню сообщения JSON.Он имеет два поля типа Child.

package forum9862100;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Parent {

    protected Child field1;
    protected Child field2;

}

Child

На класс Child может ссылаться его ключ.Мы рассмотрим этот вариант использования с XmlAdapter.Мы ссылаемся на XmlAdapter через аннотацию @XmlJavaTypeAdapter.

package forum9862100;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlJavaTypeAdapter(ChildAdapter.class)
@XmlAccessorType(XmlAccessType.FIELD)
public class Child {

    protected String id;
    protected String foo;
    protected Integer bar;

}

ChildAdapter

Ниже приведена реализация XmlAdapter.Это XmlAdapter с состоянием, что означает, что нам нужно будет установить экземпляр для Marshaller и Unmarshaller.

package forum9862100;

import java.util.*;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class ChildAdapter extends XmlAdapter<ChildAdapter.AdaptedChild, Child>{

    private List<Child> childList = new ArrayList<Child>();
    private Map<String, Child> childMap = new HashMap<String, Child>();

    public static class AdaptedChild extends Child {
        @XmlElement(name="$ref")
        public String reference;
    }

    @Override
    public AdaptedChild marshal(Child child) throws Exception {
        AdaptedChild adaptedChild = new AdaptedChild();
        if(childList.contains(child)) {
            adaptedChild.reference = child.id;
        } else {
            adaptedChild.id = child.id;
            adaptedChild.foo = child.foo;
            adaptedChild.bar = child.bar;
            childList.add(child);
        }
        return adaptedChild;
    }

    @Override
    public Child unmarshal(AdaptedChild adaptedChild) throws Exception {
        Child child = childMap.get(adaptedChild.reference);
        if(null == child) {
            child = new Child();
            child.id = adaptedChild.id;
            child.foo = adaptedChild.foo;
            child.bar = adaptedChild.bar;
            childMap.put(child.id, child);
        }
        return child;
    }

}

Демо

Код нижедемонстрирует, как задать состояние XmlAdapter для Marshaller и Unmarshaller:

package forum9862100;

import java.io.File;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

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

        StreamSource json = new StreamSource(new File("src/forum9862100/input.json"));
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty("eclipselink.media-type", "application/json");
        unmarshaller.setProperty("eclipselink.json.include-root", false);
        unmarshaller.setAdapter(new ChildAdapter());
        Parent parent = (Parent) unmarshaller.unmarshal(json, Parent.class).getValue();

        System.out.println(parent.field1 == parent.field2);

        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.setAdapter(new ChildAdapter());
        marshaller.marshal(parent, System.out);
    }

}

Выход

Ниже приведен вывод из запуска демонстрационного кода,Обратите внимание, как два экземпляра Child проходят проверку личности.

true
{
   "field1" : {
      "id" : "2",
      "foo" : "val",
      "bar" : 4
   },
   "field2" : {
      "$ref" : "2"
   }}

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

0 голосов
/ 25 марта 2012

Я бы использовал одну из множества библиотек сериализации Object to JSon. Многие из библиотек являются расширяемыми, но я подозреваю, что добавление ссылок может быть сложным, если вы не сделаете прагматичный выбор относительно того, когда их использовать.

...