2

オブジェクトをJSONにマッピングしていますがParameters、型と呼ばれる1つの変数に問題がありますList <SimilarityParameter>

SimilarityParameterこのように見えます:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SimilarityParameter {

    private String name;
    private String type;

    public SimilarityParameter() {

    }

    public SimilarityParameter(String name, String type) {
        this.name = name;
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

このリストが大きい場合、すべてがOKです。JSONは次のようになります

{
  "parameters":[
    {
      "name":"threshold",
      "type":"Double"
    },
    {
      "name":"numberOfResults",
      "type":"Integer"
    }
  ]
}

クライアント側でJSONエンコードした後、パラメーターの配列があるため、これは問題ありません。

問題は、リストのサイズが1の場合です。マッパーはそれを論理的に次の宛先に転送します。

{
  "parameters":{
    "name":"numberOfResults",
    "type":"Integer"
  }
}

クライアントがデコードすると、このJSONはとを含む配列を取得しnameますtype。クライアント側で不整合が発生します。

サイズ1のリストをこれにマップしたいと思います:

{
  "parameters":[
    {
      "name":"threshold",
      "type":"Double"
    }
  ]
}

したがって、1つのパラメータを含む配列をエンコードした後。

応答は次のようになります。

@XmlRootElement(name = "availableSimilarities")
@XmlAccessorType(XmlAccessType.FIELD)
public class SimilarityInfoResult {

    private String similarityName;
    private List <SimilarityParameter> parameters;

    public SimilarityInfoResult() {

    }

    public SimilarityInfoResult(String similarityName, List<SimilarityParameter> parameters) {
        this.similarityName = similarityName;
        this.parameters = parameters; 
    }

    public String getName() {
        return similarityName;
    }

    public void setName(String similarityName) {
        this.similarityName = similarityName;
    }

    public List<SimilarityParameter> getParameters() {
        return parameters;
    }

    public void setParameters(List<SimilarityParameter> parameters) {
        this.parameters = parameters;
    }


}

これを達成することは可能ですか?

4

1 に答える 1

0

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

問題は、リストのサイズが1の場合です。マッパーはそれを論理的に次の宛先に転送します。

JAXB仕様自体はJSONバインディングをカバーしていないため、XMLイベントをJSONとの間で変換するJettisonなどのライブラリで実装が使用されることがあり、サイズ1のコレクションが正しく表示されないなどの問題が発生します。これは、Jettison(および同様の)ライブラリがコレクションを検出できるのは、要素が複数回出現するのを確認した場合のみであるためです。


これを達成することは可能ですか?

JAXBのEclipseLinkMOXy実装は、ネイティブJSONバインディングを提供します。これは、サイズ1のコレクションなどのアイテムが適切にJSONに変換されることを意味します。

jaxb.properties

MOXyをJAXBプロバイダーとして指定するには、jaxb.properitesドメインモデルと同じパッケージで呼び出されるファイルを次のエントリに含める必要があります。

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

デモ

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[] {SimilarityInfoResult.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource json = new StreamSource("src/forum15316288/input.json");
        SimilarityInfoResult result = unmarshaller.unmarshal(json, SimilarityInfoResult.class).getValue();

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

}

input.json / Output

{
   "parameters" : [ {
      "name" : "threshold",
      "type" : "Double"
   } ]
}

詳細については

于 2013-03-11T10:34:06.243 に答える