【问题标题】:JAXB mapping for a map地图的 JAXB 映射
【发布时间】:2012-07-04 23:24:47
【问题描述】:

使用JAXB,如何在下面映射<entry key="childResources">

我尝试将其映射到 Map、@XmlRootElement 注释类列表和其他方式,但没有成功。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<map>    
  <entry key="extraProperties">        
    <map>            
      <entry key="methods">                
        <list>                    
          <map>                        
            <entry key="name" value="GET" />
          </map>                    
          <map />                    
          <map>                        
            <entry key="name" value="POST" />                        
            <entry key="messageParameters">                            
              <map>                                
                <entry key="id">                                    
                  <map>                                        
                    <entry key="acceptableValues" value="" />                                        
                    <entry key="optional" value="false" />                                        
                    <entry key="defaultValue" value="" />                                        
                    <entry key="type" value="string" />
                  </map>                                
                </entry>                                
                <entry key="enabled">                                    
                  <map>                                        
                    <entry key="acceptableValues" value="" />                                        
                    <entry key="optional" value="true" />                                        
                    <entry key="defaultValue" value="true" />                                        
                    <entry key="type" value="boolean" />
                  </map>                                
                </entry>                                
                <entry key="factoryclass">                                    
                  <map>                                        
                    <entry key="acceptableValues" value="" />                                        
                    <entry key="optional" value="false" />                                        
                    <entry key="defaultValue" value="" />                                        
                    <entry key="type" value="string" />
                  </map>                                
                </entry>                                
                <entry key="description">                                    
                  <map>                                        
                    <entry key="acceptableValues" value="" />                                        
                    <entry key="optional" value="true" />                                        
                    <entry key="defaultValue" value="" />                                        
                    <entry key="type" value="string" />
                  </map>                                
                </entry>                                
                <entry key="target">                                    
                  <map>                                        
                    <entry key="acceptableValues" value="" />                                        
                    <entry key="optional" value="true" />                                        
                    <entry key="defaultValue" value="server" />                                        
                    <entry key="type" value="string" />
                  </map>                                
                </entry>                                
                <entry key="property">                                    
                  <map>                                        
                    <entry key="acceptableValues" value="" />                                        
                    <entry key="optional" value="true" />                                        
                    <entry key="defaultValue" value="" />                                        
                    <entry key="type" value="string" />
                  </map>                                
                </entry>                                
                <entry key="restype">                                    
                  <map>                                        
                    <entry key="acceptableValues" value="" />                                        
                    <entry key="optional" value="false" />                                        
                    <entry key="defaultValue" value="" />                                        
                    <entry key="type" value="string" />
                  </map>                                
                </entry>                            
              </map>                        
            </entry>                    
          </map>                
        </list>            
      </entry>            
      <entry key="commands">                
        <list />
      </entry>            
      <entry key="childResources">                
        <map>                    
          <entry key="ab/cd" value="http://localhost:4848/management/domain/resources/custom-resource/ab%2Fcd" />                    
          <entry key="xx" value="http://localhost:4848/management/domain/resources/xx" />
        </map>            
      </entry>        
    </map>    
  </entry>    
  <entry key="message" value="" />    
  <entry key="exit_code" value="SUCCESS" />    
  <entry key="command" value="custom-resource" />
</map>

【问题讨论】:

  • 一个&lt;entry&gt; 可以有a single &lt;map&gt;a single &lt;list&gt;?
  • 我猜 有一个包含多个条目的单个映射,每个条目都有一个键/值对
  • 我猜 应该映射到 Map 或 Map
  • 映射到地图时出现什么错误?
  • 为什么不使用 XPATH 表达式来获取所需的值?使用 JAXB,您可以映射文档结构,但不能使映射依赖于 key="childResources" 等属性的内容。

标签: java jaxb


【解决方案1】:

查看文档的 XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="map" type="mapType"/>
  <xs:complexType name="entryType" mixed="true">
    <xs:sequence>
      <xs:element type="mapType" name="map" minOccurs="0"/>
      <xs:element type="listType" name="list" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute type="xs:string" name="key" use="optional"/>
    <xs:attribute type="xs:string" name="value" use="optional"/>
  </xs:complexType>
  <xs:complexType name="listType" mixed="true">
    <xs:sequence>
      <xs:element type="mapType" name="map" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="mapType" mixed="true">
    <xs:sequence>
      <xs:element type="entryType" name="entry" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

将其与您为班级所做的映射进行比较。很高兴看到您提出问题的类和注释。

您可以使用 Eclipse 和 Intellij 等 IDE 的许多不同实用程序或通过 CLI 从此架构生成具有映射的模型。

【讨论】:

    【解决方案2】:

    java.util.Map 接口没有提供者来编组/解组其实例。您必须编写一个扩展 XmlAdapter 的类,并使用 @XmlJavaTypeAdapter(MyMapAdapter.class) 注释 java.util.Map 属性。

    在 Google 上寻找 jax-rs java.util.map 一段时间后,我得到了下面的代码。在我的例子中,我将我的适配器命名为 XmlStringMapAdapter 而不是 MyMapAdapter

    ServiceDefinition.java

    @XmlRootElement(name = "entry")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class ServiceDefinition {
    
        @XmlAttribute
        private String key;
    
        @XmlJavaTypeAdapter(XmlStringMapAdapter.class)
        private Map<String, String> map = new HashMap<String, String>();
    
        // getters & setters
    }
    

    EntryElement.java

    public class EntryElement {
    
        @XmlAttribute public String key;
        @XmlAttribute public String value;
    
        public EntryElement() {}
    
        public EntryElement(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }
    

    MapElement.java

    @XmlRootElement(name = "map")
    public class MapElement {
    
        @XmlElement(name = "entry")
        public List<EntryElement> entries = new ArrayList<EntryElement>();
    
        public void addEntry(String key, String value) {
            entries.add(new EntryElement(key, value));
        }
    
    }
    

    XmlStringMapAdapter.java

    public class XmlStringMapAdapter extends XmlAdapter<MapElement, Map<String, String>> {
    
        @Override
        public MapElement marshal(Map<String, String> v) throws Exception {
    
            if (v == null || v.isEmpty()) {return null;}
    
            MapElement map = new MapElement();
    
            for (String key : v.keySet()) {
                map.addEntry(key, v.get(key));
            }
    
            return map;
        }
    
        @Override
        public Map<String, String> unmarshal(MapElement v) throws Exception {
            if (v == null) {return null;}
    
            Map<String, String> map = new HashMap<String, String>(v.entries.size());
    
            for(EntryElement entry: v.entries) {
                map.put(entry.key, entry.value);
            }
    
            return map;
        }
    
    }
    

    下面是我用来测试新地图适配器的一个类。

    ServiceResouce.java

    @Path("service")
    public class ServiceResource {
    
        @Context
        private UriInfo uriInfo;
    
        @GET
        @Path("definition")
        @Produces("application/xml")
        public Response getDefinition() {
            ServiceDefinition def = new ServiceDefinition();
            UriBuilder b = uriInfo.getBaseUriBuilder();
    
            def.setKey("childResources");
            def.getMap().put("ab/cd", b.path("ab/cd").build(this).getPath());
            def.getMap().put("xx", b.path("xx").build(this).getPath());
    
            return Response.ok(def).build();
        }
    }
    

    上述资源的输出如下所示。

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <entry key="childResources">
        <map>
            <entry key="ab/cd" value="http://localhost:8080/management/resources/ab/cd" />
            <entry key="xx" value="http://localhost:8080/management/resources/xx" />
        </map>
    </entry>
    

    【讨论】:

      猜你喜欢
      • 2014-04-22
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多