我正在尝试通过 SOAP 传递 HashMap 。我正在使用 CXF wsdl2java 来创建我的模式。而且我已经为我的 HashMap 创建了一个包装器类,因为 Hashmap 本身不能通过线路传递。
然后我创建了适配器以将该 Hashmap 转变为我的 wsdl 的已知类型,但是当我的 wsdl 创建时它添加了一些不需要的抽象映射。下面是代码:
这是我的 HashMap 包装器类
@XmlRootElement(name = "testTO")
public class TestTO {
private HashMap<String, Object> mapTest;
public TestTO(){
this.mapTest = new HashMap<String, Object>();
}
@XmlJavaTypeAdapter(MapAdapter.class)
public HashMap<String, Object> getMapTest() {
return mapTest;
}
public void setMapTest(HashMap<String, Object> mapTest) {
this.mapTest = mapTest;
}
}
这是 MyMap 类,其中有一个已知的模式类型
@XmlJavaTypeAdapter(MapAdapter.class)
public class MyMap extends HashMap<String, Object>{
public final List<Entry> entryList = new ArrayList<Entry>();
}
这是上面列表中包含的条目类:
public class Entry {
@XmlAttribute
public String key;
@XmlElements({
@XmlElement(name = "byte", type = byte.class),
@XmlElement(name = "short", type = short.class),
@XmlElement(name = "int", type = int.class),
@XmlElement(name = "long", type = long.class),
@XmlElement(name = "float", type = float.class),
@XmlElement(name = "double", type = double.class),
@XmlElement(name = "char", type = char.class),
@XmlElement(name = "boolean", type = boolean.class),
@XmlElement(name = "ByteWrapper", type = Byte.class),
@XmlElement(name = "ShortWrapper", type = Short.class),
@XmlElement(name = "IntegerWrapper", type = Integer.class),
@XmlElement(name = "LongWrapper", type = Long.class),
@XmlElement(name = "FloatWrapper", type = Float.class),
@XmlElement(name = "DoubleWrapper", type = Double.class),
@XmlElement(name = "Character", type = Character.class),
@XmlElement(name = "BooleanWrapper", type = Boolean.class),
@XmlElement(name = "BigDecimal", type = BigDecimal.class),
@XmlElement(name = "String", type = String.class),
@XmlElement(name = "Date", type = Date.class)
})
public Object value;
public Entry() {
this.key = null;
this.value = null;
}
public Entry(String key, Object value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public Object getValue() {
return value;
}
}
这是我的适配器:
public class MapAdapter extends XmlAdapter<MyMap, Map<String, Object>> {
@Override
public MyMap marshal(Map<String, Object> v) throws Exception {
MyMap myMap = new MyMap();
for ( Map.Entry<String, Object> e : v.entrySet() ) {
Entry entry = new Entry();
entry.key = e.getKey();
entry.value = e.getValue();
myMap.entryList.add(entry);
}
return myMap;
}
@Override
public Map<String, Object> unmarshal(MyMap v) throws Exception {
Map<String, Object> map = new HashMap<String,Object>();
for ( Entry e : v.entryList ) {
map.put(e.key, e.value);
}
return map;
}
}
但我的 wsdl 正在生成以下内容:
<xs:element minOccurs="0" name="foo" type="tns:testTO"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="testTO">
<xs:sequence>
<xs:element minOccurs="0" name="mapTest" type="tns:myMap"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="myMap">
<xs:complexContent>
<xs:extension base="tns:hashMap">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="entryList" nillable="true" type="tns:entry"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="hashMap">
<xs:complexContent>
<xs:extension base="tns:abstractMap">
<xs:sequence/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType abstract="true" name="abstractMap">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="entry">
<xs:sequence>
<xs:choice minOccurs="0">
<xs:element name="byte" type="xs:byte"/>
<xs:element name="short" type="xs:short"/>
<xs:element name="int" type="xs:int"/>
<xs:element name="long" type="xs:long"/>
<xs:element name="float" type="xs:float"/>
<xs:element name="double" type="xs:double"/>
<xs:element name="char" type="xs:unsignedShort"/>
<xs:element name="boolean" type="xs:boolean"/>
<xs:element name="ByteWrapper" type="xs:byte"/>
<xs:element name="ShortWrapper" type="xs:short"/>
<xs:element name="IntegerWrapper" type="xs:int"/>
<xs:element name="LongWrapper" type="xs:long"/>
<xs:element name="FloatWrapper" type="xs:float"/>
<xs:element name="DoubleWrapper" type="xs:double"/>
<xs:element name="Character" type="xs:unsignedShort"/>
<xs:element name="BooleanWrapper" type="xs:boolean"/>
<xs:element name="BigDecimal" type="xs:decimal"/>
<xs:element name="String" type="xs:string"/>
<xs:element name="Date" type="xs:dateTime"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="key" type="xs:string"/>
</xs:complexType>
我查看了我在这里发现的其他多个案例,但没有一个能够解决我的问题,我什至引用了 http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html 但是 java 的 wsdl 似乎把模式搞乱了。
谢谢。
最佳答案
我相信您不必编写自定义 XmlAdapter
编码/解码 Map<String, Object
使用最新的 JAXB 版本。以下示例对我来说效果很好。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "foo")
public class Foo {
private Map<String, Object> map = new HashMap<String, Object>();
public Map<String, Object> getMap() {
return params;
}
}
这导致了一个模式:
<xs:complexType name="foo">
<xs:sequence>
<xs:element name="map">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="entry">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="key" type="xs:string"/>
<xs:element minOccurs="0" name="value" type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
然后您应该能够解码以下 xml:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://your.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<soapenv:Header/>
<soapenv:Body>
<foo>
<params>
<entry>
<key>string</key>
<value xsi:type="xs:string">5</value>
</entry>
<entry>
<key>integer</key>
<value xsi:type="xs:int">54</value>
</entry>
</params>
</foo>
</soapenv:Body>
</soapenv:Envelope>
只是不要忘记 xs 和 xsi namespace 。您甚至可以将自定义类型作为值传递,而不仅仅是简单的 xsi 类型。然后你必须确保你已经指定了正确的 xsi:type.
关于java - 使用 JAXB 通过 SOAP 传递 HashMap<String,Object>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16086385/