2

我将一个对象映射到 JSON 并且有一个名为Parameterstype 的变量的问题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;
    }
}

当这个列表很大时,一切都很好。JSON看起来像这样

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

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

问题是当 List 的大小为 1 时。Mapper 将其逻辑传输到:

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

当客户端解码此 JSON 时,会得到一个包含name和的数组type。它会导致客户端的不一致。

我想将大小为 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;
    }


}

有可能实现这一目标吗?

4

1 回答 1

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

}

输入.json/输出

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

了解更多信息

于 2013-03-11T10:34:06.243 回答