6

私はこの @XmlRootElement クラス Person を持っています。

    @XmlRootElement
    class Person {
        private String desc;
    }

そしてリターン内容は

    {"Person": {"desc": "abc"} }

ルートラッパーは本当に必要ないので、コンテンツを次のようにしたい

    {"desc": "abc"}

JaxB経由でこれを達成できますか? もしそうなら、どのように?ありがとう!

4

2 に答える 2

4

注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。

esseplymale JAXB (JSR-222) が回答したように、JSON バインディングではなく XML をカバーしています。ただし、JAXB は頻繁に直接使用されます (JAXB impl は Jettison などで使用され、JSON を StAX イベントとの間で変換します。参照: http://blog.bdoughan.com/2011/04/jaxb-and-json-via-jettison. html ) および間接的に (JAXB アノテーションのサブセットを解釈する JSON バインディングの実装)、このスペースで。

以下は、EclipseLink MOXy を JAXB プロバイダーとして活用することで、ユース ケースを実現する方法です。

Java モデル

以下は、Person質問のクラスです。@XmlAccessorType(XmlAccessType.FIELD)アクセサー メソッドの追加を避けるために 、注釈を追加しました(参照: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html )。

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
class Person {

    private String desc;

}

jaxb.properties

MOXy を JAXB プロバイダーとして使用jaxb.propertiesし、次のエントリを使用して、ドメイン モデルと同じパッケージで呼び出されるファイルを含める必要があります ( http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-asを参照)。 -your.html )。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

デモコード

デモ

デモ コードで注意すべき点がいくつかあります。

  1. プロパティは、JAXBContextProperties.MEDIA_TYPEMOXy を JSON バインディング モードにするために使用されます。
  2. このJAXBContextProperties.JSON_INCLUDE_ROOTプロパティは、ルート要素を省略するようMOXyに指示するために使用されます。
  3. unmarshalルート要素が省略されている場合は、パラメータを取るメソッドの 1 つを使用して、アンマーシャリングするタイプを MOXy に伝える必要がありClassます。
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>(2);
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Person.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource json = new StreamSource("src/forum18417466/input.json");
        Person person = unmarshaller.unmarshal(json, Person.class).getValue();

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

}

input.json/出力

{
   "desc" : "abc"
}
于 2013-08-26T13:14:56.130 に答える
3

JAXB は XML 用の API であり、JSON 用ではありません。

ただし、JAXB アノテーションを利用できる JSON ライブラリ (少なくとも Jackson) がいくつかあります。どちらを使用されているかわかりません。そのため、どのようにサポートすればよいかわかりません。(Jersey フレームワークでこれを使用している場合、JSON シリアル化に Jackson を使用します。) JSON 出力でルート要素の「ラッピング」を構成できるようにするには、使用している JSON ライブラリを構成する必要があります。

Jackson でこれをテストするために、この簡単な Groovy スクリプトを作成しました。

@Grab('com.fasterxml.jackson.core:jackson-databind:2.2.2')
import javax.xml.bind.annotation.XmlRootElement
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature

@XmlRootElement
public class Person {
  public String desc = "howdy"
}

Person p = new Person()
ObjectMapper om = new ObjectMapper().enable(SerializationFeature.WRAP_ROOT_VALUE)
println om.writeValueAsString(p)

上記のように、JSON を出力します。

{"Person":{"desc":"howdy"}}

その部分を取り出すと、次のようになり.enable(SerializationFeature.WRAP_ROOT_VALUE)ます。

{"desc":"howdy"}

したがって、Jackson を使用している場合は、バックグラウンドで使用されている ObjectMapper が設定されているように見えWRAP_ROOT_VALUEます。これをオフにするだけです。

于 2013-08-24T17:34:55.467 に答える