JAXB Java工具将java.util.Map绑定

14

我有一个 JSON 响应,它看起来像下面这样:

{
    "data": [
        {
            "param1": "value1",
            "param2": "value2",
                    .
                    .
                    .
            "paramN": "valueN"
        }
    ]
}

我不知道参数的名称和数量,因此我需要将所有这些参数绑定到一个java.util.Map字段中,该字段由<"paramX", "valueX">元组组成。为了做到这一点,我尝试了以下代码,但“parametersMap”字段返回null。

@XmlRootElement(name="data")
@XmlAccessorType(XmlAccessType.FIELD)
public class Parameters {
    @XmlElement
    private Map<String,String> parametersMap;

    // Getter and setter for parametersMap
}

我该如何使用JAXB注解实现这样的绑定?

先行致谢。


从另一篇帖子中我刚刚了解到jersey(重新)使用JAXB注释。http://stackoverflow.com/questions/1261593/binding-a-json-to-a-java-class-using-jaxb - Andreas Dolk
1
是的,JAXB用于XML绑定,但它也可以与Jersey一起用于将JSON输入绑定到Java对象上。 - ovunccetin
EclipseLink JAXB(MOXy)还提供了利用JAXB注释进行JSON绑定的功能:http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html - bdoughan
你使用的是哪个版本的Jersey? - dataoz
1
我认为这个链接可以帮助你:https://dev59.com/w1fUa4cB1Zd3GeqPMvPv - рüффп
显示剩余2条评论
1个回答

8
基本上你需要一个 XML 适配器。你可以在 KeyValue 类的名称上调整,以获得所需的特定输出。
Parameter.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Map;

@XmlRootElement(name = "data")
@XmlAccessorType(XmlAccessType.FIELD)
public class Parameters {

    @XmlJavaTypeAdapter(value = Adapter.class)
    private Map<String, String> parametersMap;

    // Getter and setter for parametersMap
}

Adapter.java

import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Adapter extends XmlAdapter<List<KeyValue>, Map<String, String>> {

    @Override
    public Map<String, String> unmarshal(List<KeyValue> v) throws Exception {
        Map<String, String> map = new HashMap<>(v.size());
        for (KeyValue keyValue : v) {
            map.put(keyValue.key, keyValue.value);
        }
        return map;
    }

    @Override
    public List<KeyValue> marshal(Map<String, String> v) throws Exception {
        Set<String> keys = v.keySet();
        List<KeyValue> results = new ArrayList<>(v.size());
        for (String key : keys) {
            results.add(new KeyValue(key, v.get(key)));
        }
        return results;
    }
}

KeyValue.java 在此处放置更好的JAXB标签。

import javax.xml.bind.annotation.XmlType;

@XmlType
public class KeyValue {
    public KeyValue() {
    }

    public KeyValue(String key, String value) {
        this.key = key;
        this.value = value;
    }

    //obviously needs setters/getters
    String key;
    String value;
}

我在Parameters.java文件中,Map声明的那一行遇到了com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions - koppor
1
答案 https://www.tomasmalmsten.com/2012/05/unmarshall-marshall-java-maps-xml-jaxb/ 将 List<KeyValue> 包装在另一个辅助类中。这可以避免 IllegalAnnotationsException - koppor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接