Статьи

MOXy’s @XmlVariableNode — Пример схемы JSON

Мы находимся в процессе добавления возможности создания JSON-схемы из модели вашего домена в EclipseLink MOXy . Для этого мы создали новое отображение узла переменных. В этой статье я продемонстрирую новое сопоставление путем сопоставления модели Java с JSON-схемой.

Вы можете попробовать это сегодня, используя ночную сборку EclipseLink 2.6.0:

Схема JSON (input.json / Output)

Ниже приведен «Основной пример», взятый из http://json-schema.org/examples.html . Обратите внимание, что тип имеет много свойств, но они не отображаются в виде массива JSON. Вместо этого они отображаются как отдельные объекты JSON, связанные с именем свойства.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
{
    "title": "Example Schema",
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "lastName": {
            "type": "string"
        },
        "age": {
            "description": "Age in years",
            "type": "integer",
            "minimum": 0
        }
    },
    "required": ["firstName", "lastName"]
}

Модель Java

Ниже приведена модель Java, которую мы будем использовать для этого примера.

JsonSchema (свойства, хранящиеся в списке)

В этом Java-представлении схемы JSON у нас есть класс, который имеет коллекцию объектов Property . Вместо представления коллекции по умолчанию (см .: Привязка к JSON и XML — Обработка коллекций ), мы хотим, чтобы каждое свойство было связано с его именем . Мы можем сделать это, используя аннотацию @XmlVariableNode . С его помощью мы указываем поле / свойство из целевого объекта, который должен использоваться в качестве ключа.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
package blog.variablenode.jsonschema;
 
import java.util.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlVariableNode;
 
@XmlAccessorType(XmlAccessType.FIELD)
public class JsonSchema {
 
    private String title;
 
    private String type;
 
    @XmlElementWrapper
    @XmlVariableNode("name")
    public List<Property> properties;
 
    private List<String> required;
 
}

JsonSchema (Свойства, хранящиеся на карте)

В этой версии класса JsonSchema мы изменили свойство типа свойств с свойства List <Property> на Map <String, Property> . Аннотация остается той же самой, разница в том, что когда @XmlVariableNode используется на карте, имя узла переменной используется в качестве ключа карты.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
package blog.variablenode.jsonschema;
 
import java.util.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlVariableNode;
 
@XmlAccessorType(XmlAccessType.FIELD)
public class JsonSchema {
 
    private String title;
 
    private String type;
 
    @XmlElementWrapper
    @XmlVariableNode("name")
    public Map<String, Property> properties;
 
    private List<String> required;
 
}

Имущество

Чтобы предотвратить маршализацию поля имени, нам нужно аннотировать его с помощью @XmlTransient (см. JAXB и Unmapped Properties ).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
package blog.variablenode.jsonschema;
 
import javax.xml.bind.annotation.*;
 
@XmlAccessorType(XmlAccessType.FIELD)
public class Property {
 
    @XmlTransient
    private String name;
 
    private String description;
 
    private String type;
 
    private Integer minimum;
 
}

Демонстрационный код

Ниже приведен пример кода, который вы можете использовать, чтобы доказать, что все работает.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package blog.variablenode.jsonschema;
 
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[] {JsonSchema.class}, properties);
 
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource json = new StreamSource("src/blog/variablenode/jsonschema/input.json");
        JsonSchema jsonSchema = unmarshaller.unmarshal(json, JsonSchema.class).getValue();
 
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(jsonSchema, System.out);
    }
 
}

Внешние метаданные

MOXy также предлагает внешний документ сопоставления, который позволяет вам предоставлять метаданные для сторонних объектов или применять альтернативные сопоставления для вашей модели (см .: Отображение объекта в несколько схем XML — пример погоды ). Ниже приведен документ сопоставления для этого примера.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0"?>
<xml-bindings
    package-name="blog.variablenode.jsonschema"
    xml-accessor-type="FIELD">
    <java-types>
        <java-type name="JsonSchema">
            <java-attributes>
                <xml-variable-node
                    java-attribute="properties" java-variable-attribute="name">
                    <xml-element-wrapper/>
                </xml-variable-node>
            </java-attributes>
        </java-type>
        <java-type name="Property">
            <java-attributes>
                <xml-transient java-attribute="name"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Ссылка: MOXy’s @XmlVariableNode — пример схемы JSON от нашего партнера по JCG Блэза Дафана из блога Java XML & JSON Binding .