列表大小为1的Java JSON映射

时间:2013-03-09 21:47:57

标签: java xml json java-ee jaxb

我正在将对象映射到JSON,并且遇到一个名为Parameters的名为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;
    }
}

当此List很大时,一切正常。 JSON看起来像这样

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

这没关系,因为在客户端进行JSON编码后,我有一个参数数组。

问题是当List的大小为1. Mapper将其逻辑转移到:

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

当客户端解码此JSON时,获取包含nametype的数组。它会导致客户端出现不一致。

我想将大小1的列表映射到此:

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

编码包含一个参数的数组后。

这是响应的外观:

@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;
    }


}

有可能实现这个目标吗?

1 个答案:

答案 0 :(得分:0)

注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。

  

问题是当List的大小为1. Mapper在逻辑上传输它   到:

JAXB规范本身并不包含JSON绑定,因此有时实现与Jettison这样的库一起使用,这些库将XML事件转换为JSON或从JSON转换,并且出现问题,例如大小为1的集合被错误地表示。这是因为Jettison(和类似的)库只能在看到元素出现多次时才能检测到集合。


  

有可能实现这个目标吗?

JAXB的 EclipseLink MOXy 实现提供本机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 /输出

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

了解更多信息