2

JAXB アノテーション付きの POJO があります。xml と json へのマーシャリングはうまく機能しますが、json ではルート タグが失われるため、xml と json は互換性がありません。jsonの方が理にかなっていることはわかっていますが、それでもルート要素が必要です。それを取得する方法はありますか?

@XmlRootElement(name = XmlConsts.ELEMENT)
@XmlAccessorType(XmlAccessType.FIELD)
public class Element {
    private static final String MULTIPLE_VALUE_DELIMITER = ",";

    @XmlElement(name = XmlConsts.PROPERTIES)
    @XmlJavaTypeAdapter(JaxbMapAdapter.class)
    private final Map<String, String> entries;

    @XmlAttribute(name = XmlConsts.ELEMENT_TYPE, required = false)
    public String getType() {
        return entries.get(XmlConsts.ELEMENT_TYPE);
    }
    ...

結果xml:

<element type="rule.record">
  <properties>
    <property name="min" value="0"/>
    <property name="id" value="1773"/>
...

結果のjson:

{"type":"rule.record","properties":{
"property":[
{"name":"min","value":"0"},
{"name":"id","value":"1773"}

ここに見られるように、「要素」タグは json で失われます。ルート要素を取得する方法はありますか?

4

1 に答える 1

2

以下は、実行している環境に基づいてこれを行うことができるいくつかの方法です。

スタンドアロンの例

標準の JAXB API を使用する場合、MOXy は JSON にマーシャリングするときにルート要素を含めます。この動作は、JAXBContextProperties.JSON_INCLUDE_ROOTプロパティを使用して変更できます。falseの作成時にに設定されていた場合はJAXBContext、 で に戻すことができtrueますMarshaller

import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.MarshallerProperties;

public class Demo {

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

        Foo foo = new Foo();
        foo.setBar("Hello World");

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

}

JAX-RSとMOXyJsonProvider

MOXy にはMessageBodyReader/の実装が含まれているため、 MessageBodyWriterMOXy を JSON バインディング プロバイダーとして簡単に構成できます。デフォルトMOXyJsonProviderでは、ルート要素を含めないように構成されています。Applicationこれは、以下のような JAX-RS クラスに構成済みのインスタンスを設定することで変更できます。

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class FooApplication  extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>(1);
        set.add(ExampleService.class);
        return set;
    }

    @Override
    public Set<Object> getSingletons() {
        MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
        moxyJsonProvider.setIncludeRoot(true);

        HashSet<Object> set = new HashSet<Object>(1);
        set.add(moxyJsonProvider);
        return set;
    }

} 

詳細については

Jersey/GlassFish のデフォルトの JSON バインディング プロバイダーとしての MOXy

MOXy を Jersey/GlassFish のデフォルトの JSON バインディング プロバイダーとして使用している場合は、MoxyJsonConfig次のようにクラスを利用できます。

import javax.ws.rs.ext.*;
import org.glassfish.jersey.moxy.json.MoxyJsonConfig;

@Provider
public class MOXyJsonContextResolver implements ContextResolver<MoxyJsonConfig> {

    private final MoxyJsonConfig config;

    public MOXyJsonContextResolver() {
        config = new MoxyJsonConfig()
            .setIncludeRoot(true);
    }

    @Override
    public MoxyJsonConfig getContext(Class<?> objectType) {
        return config;
    }

}

詳細については

于 2013-10-01T10:03:33.393 に答える