简体   繁体   English

马歇尔/解马歇尔地图

[英]Marshall/Unmarshall Map

@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class ItemSubstitutionRequestDTO { public ItemSubstitutionRequestDTO() { } private List<Map<String,Integer>> substituteFor=new ArrayList<Map<String,Integer>>(); private String orderId; public List<Map<String,Integer>> getSubstituteFor() { return substituteFor; } public void setSubstituteFor(List<Map<String,Integer>> substituteFor) { this.substituteFor = substituteFor; } public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } }

Final result ERROR :最终结果错误

java.util.Map is an interface, and JAXB can't handle interfaces. java.util.Map 是一个接口,JAXB 不能处理接口。

I can't get JaxB to be able to marshall/unmarshall instances of Map.I tried other annotation also and found this is one of the possible way to solve the above error but nothing is woking.我无法让 JaxB 能够编组/解组 Map 的实例。我也尝试了其他注释,发现这是解决上述错误的可能方法之一,但没有任何效果。

Below is the input json which is coming from UI side下面是来自 UI 端的输入 json

{ "itemSubstitutionRequestDTO": { "substituteFor": [{"41712":2}], "orderId": "1073901", } } { "itemSubstitutionRequestDTO": { "substituteFor": [{"41712":2}], "orderId": "1073901", } }

You didn't write how your XML content within the <substituteFor> element would look like.您没有编写<substituteFor>元素中的 XML 内容的外观。 Therefore I assume something like this:因此,我假设是这样的:

<itemSubstitutionRequestDTO>
    <substituteFor>
        <item>
            <key>x</key>
            <value>23</value>
        </item>
        <item>
            <key>y</key>
            <value>3</value>
        </item>
    </substituteFor>
    <orderId>abc</orderId>
</itemSubstitutionRequestDTO>

As the JAXB error message already told you, it can't handle types with an interface between the < > , like for example your List<Map<String,Integer>> .正如 JAXB 错误消息已经告诉您的那样,它无法处理具有< >之间的接口的类型,例如您的List<Map<String,Integer>> However it can handle types with a normal class between < > , like List<SubstitutionMap> .但是,它可以处理具有< >之间的普通类的类型,例如List<SubstitutionMap>

So the first step is to rewrite your ItemSubstitutionRequestDTO class so that it does not use List<Map<String,Integer>> , but instead List<SubstitutionMap> .因此,第一步是重写您的ItemSubstitutionRequestDTO类,使其不使用List<Map<String,Integer>> ,而是使用List<SubstitutionMap> You need to write the SubstitutionMap class (not an interface) by yourself.您需要自己编写SubstitutionMap类(不是接口)。 But it can be extremely simple:但它可以非常简单:

public class SubstitutionMap extends HashMap<String, Integer> {
}

Now JAXB doesn't throw an error anymore, but it still doesn't know how to marshal/unmarshal a SubstitutionMap .现在 JAXB 不再抛出错误,但它仍然不知道如何编组/解组SubstitutionMap Therefore you need to write an XmlAdapter for it.因此,您需要为它编写一个XmlAdapter Let's call it SubstitutionMapAdapter .我们称之为SubstitutionMapAdapter To make JAXB aware of this adapter, you need to annotate the substituteFor property in your ItemSubstitutionRequestDTO class with:为了使JAXB知道这个适配器,你需要注释substituteFor财产在你ItemSubstitutionRequestDTO与类:

@XmlJavaTypeAdapter(SubstitutionMapAdapter.class)

The adapter's job is to do the actual conversion from SubstitutionMap to an array of SubstitutionMapElement s and vice versa.适配器的工作是进行从SubstitutionMapSubstitutionMapElement数组的实际转换,反之亦然。 Then JAXB can handle the SubstitutionMapElement array by itself.然后 JAXB 可以自己处理SubstitutionMapElement数组。

public class SubstitutionMapAdapter extends XmlAdapter<SubstitutionMapElement[], SubstitutionMap> {

    @Override
    public SubstitutionMap unmarshal(SubstitutionMapElement[] elements) {
        if (elements == null)
            return null;
        SubstitutionMap map = new SubstitutionMap();
        for (SubstitutionMapElement element : elements)
            map.put(element.getKey(), element.getValue());
        return map;
    }

    @Override
    public SubstitutionMapElement[] marshal(SubstitutionMap map) {
        // ... (left to you as exercise)
    }
}

The class SubstitutionMapElement is just a simple container for a key and a value. SubstitutionMapElement类只是一个键和值的简单容器。

@XmlAccessorType(XmlAccessType.FIELD)
public class SubstitutionMapElement {

    private String key;
    private int value;
    
    // ... constructors, getters, setters omitted here for brevity
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM