如何使用JAXB和Spring编组非字符串对象

时间:2012-10-07 22:12:18

标签: xml spring object jaxb

我试图关注this教程,以便使用Spring框架创建自己的restful 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的String版本的标签,例如

<inetAddress>192.168.1.1</inetAddress>

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

2 个答案:

答案 0 :(得分:1)

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

示例

答案 1 :(得分:1)

感谢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>