马歇尔/马歇尔地图

时间:2020-08-29 15:48:35

标签: java xml jaxb marshalling unmarshalling

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

最终结果错误

java.util.Map是一个接口,JAXB无法处理接口。

我无法让JaxB能够编组/解散Map实例。我也尝试了其他注释,发现这是解决上述错误的一种可能方法,但没什么问题。

下面是来自UI端的输入json

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

1 个答案:

答案 0 :(得分:0)

您没有写出XML内容在 <substituteFor>元素看起来像。 因此,我假设是这样的:

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

正如JAXB错误消息已经告诉您的那样, 它无法使用< >之间的接口来处理类型, 例如您的List<Map<String,Integer>>。 但是,它可以处理< >之间具有常规类的类型, 像List<SubstitutionMap>

所以第一步是重写您的ItemSubstitutionRequestDTO类 因此它不使用List<Map<String,Integer>>,而是使用List<SubstitutionMap>。 您需要自己编写SubstitutionMap类(而不是接口)。 但这可能非常简单:

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

现在,JAXB不再抛出错误,但是仍然不知道如何对SubstitutionMap进行封送。 因此,您需要为此编写一个XmlAdapter。 我们称之为SubstitutionMapAdapter。 为了使JAXB知道此适配器,您需要注释substituteFor 您的ItemSubstitutionRequestDTO类中的属性,

@XmlJavaTypeAdapter(SubstitutionMapAdapter.class)

适配器的工作是从SubstitutionMap进行实际转换 到SubstitutionMapElement数组中,反之亦然。 然后,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)
    }
}

SubstitutionMapElement类只是键和值的简单容器。

@XmlAccessorType(XmlAccessType.FIELD)
public class SubstitutionMapElement {

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