【问题标题】:How to marshall non-string objects with JAXB and Spring如何使用 JAXB 和 Spring 编组非字符串对象
【发布时间】:2012-09-28 04:59:15
【问题描述】:

我试图按照this 教程来使用 Spring 框架创建我自己的宁静 Web 服务。 客户端发出 GET 请求,比如说

http://api.myapp/app/students

服务器返回一个xml版本的对象教室:

@XmlRootElement(name = "class")
    public class Classroom {

    private String classId = null;
    private ArrayList<Student> students = null;

    public Classroom() {
    }
    public String getClassId() {
        return classId;
    }
    public void setClassId(String classId) {
        this.classId = classId;
    }
    @XmlElement(name="student")
    public ArrayList<Student> getStudents() {
        return students;
    }
    public void setStudents(ArrayList<Student> students) {
        this.students = students;
    }
    }

对象 Student 是另一个只包含字符串的 bean。

在我的 app-servlet.xml 中,我复制了以下几行:

<bean id="studentsView" class="org.springframework.web.servlet.view.xml.MarshallingView">
    <constructor-arg ref="jaxbMarshaller" />
</bean>

<!-- JAXB2 marshaller. Automagically turns beans into xml -->
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
        <list>
            <value>com.spring.datasource.Classroom</value>
            <value>com.spring.datasource.Student</value>
        </list>
    </property>
</bean>

现在我的问题是:如果我想插入一些非字符串对象作为类变量怎么办?假设我想要一个包含 InetAddress 的字符串版本的标签,例如

<inetAddress>192.168.1.1</inetAddress>

如何强制 JAXB 调用 inetAddress.toString() 方法,使其在 xml 中显示为字符串?在返回的 xml 中,非字符串对象被忽略!

【问题讨论】:

    标签: xml spring object jaxb


    【解决方案1】:

    您可以使用XmlAdapter 来控制如何将对象从 XML 转换为。在您的XmlAdapter 中,您将编写将对象转换为String 或从String 转换的逻辑。

    示例

    【讨论】:

      【解决方案2】:

      感谢 Blaise 和 this 的回答,我设法设置了一切。只是把它们放在一起,这是我的情况:

      对象设备是:

      @XmlRootElement(name="device")
      public class Device {
          private String id;
          private String name;
          private String location;
      
          private InetSocketAddress address;
          private InetSocketAddress gatewayAddress;
      
          (omitted setters and getters...)        
      }
      

      InetSockeAddressAdapter:

      public class InetSocketAddressAdapter extends XmlAdapter<String, InetSocketAddress>{
          @Override
          public String marshal(InetSocketAddress v) throws Exception {
              return v.toString();
          }
          @Override
          public InetSocketAddress unmarshal(String v) throws Exception {
              String[] comp = v.split(":");
              return new InetSocketAddress(comp[0], new Integer(comp[1]));
          }
      
      }
      

      将 package-info.java 放入对象和适配器的包中(使用 eclipse 作为简单文件创建,因为 IDE 不允许我创建名为 package-info 的类):

      @XmlJavaTypeAdapters({
                  @XmlJavaTypeAdapter(type=InetSocketAddress.class, 
                      value=InetSocketAddressAdapter.class)})
      package com.enrico.apiserver.domain;
      
      import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
      

      我们必须在其中声明 bean 的 *-servlet.xml 行:

      <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
              <property name="classesToBeBound">
                  <list>
                      <value>com.enrico.apiserver.domain.Device</value>
                  </list>
              </property>
              <property name="adapters">
                  <list>
                      <bean class="com.enrico.apiserver.domain.InetSocketAddressAdapter" />
                  </list>
              </property>
          </bean>
      

      【讨论】:

        猜你喜欢
        • 2013-01-24
        • 2018-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 2011-07-24
        • 1970-01-01
        相关资源
        最近更新 更多