WebService传递XML文档,当然也可以传递JSON对象。这节我只针对传递XML,那么JAVA绑定成XML,服务端将XML解析成Java对象有什么工具可用吗,其实这样的工具多的是。这里我选择一个比较简单的JAXB工具来讲解一下。
JAXB(Java Architecture for XML Binding)提供了一个快速而方便的方式绑定XML Schemas和java,使java程序员能够很方便的在java应用程序中处理XML数据。JAXB提供了将XML文档解组为java内容树的方法,以及将java内容树重新编组回XML文档的方法。JAXB同样也提供了一种从java对象生成XML Schema的方式。
一、JAXB充当的角色
JAXB中常用的注解
二、简单示例
1、@XmlRootElement
POJO:
package org.wy.pojo;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
private String name = "wy";
private String sex = "man";
public int age = 20;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
JaxbTest.java
package org.wy.jaxb;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.wy.pojo.User;
public class JaxbTest {
public static void main(String[] args) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(User.class);
//JavaObject ---> XML
Marshaller marshaller = context.createMarshaller();
User user = new User();
marshaller.marshal(user, System.out);
System.out.println();
// XML---> JavaObject
Unmarshaller unmarshaller = context.createUnmarshaller();
String str = "<user><age>23</age></user>";
user = (User)unmarshaller.unmarshal(new StringReader(str));
System.out.println(user.age);
}
}
输出结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user><age>20</age><name>wy</name></user>
23
从输出结果看到 性别没有转换到xml中,原因可以从后接口XmlAccessorType.java中找到原因
我们可以看到如下
@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE})
public @interface XmlAccessorType {
/**
* Specifies whether fields or properties are serialized.
*
* @see XmlAccessType
*/
XmlAccessType value() default XmlAccessType.PUBLIC_MEMBER;
}
默认处理方式PUBLIC_MEMBER,处理public的。但是name是private的也转换成功了,原因是name被设置成了属性。
XmlAccessorType 有几种处理方式哪?
查看枚举类XmlAccessType.java
public enum XmlAccessType {
/**
* Every getter/setter pair in a JAXB-bound class will be automatically
* bound to XML, unless annotated by {@link XmlTransient}.
*
* Fields are bound to XML only when they are explicitly annotated
* by some of the JAXB annotations.
*/
PROPERTY,
/**
* Every non static, non transient field in a JAXB-bound class will be automatically
* bound to XML, unless annotated by {@link XmlTransient}.
*
* Getter/setter pairs are bound to XML only when they are explicitly annotated
* by some of the JAXB annotations.
*/
FIELD,
/**
* Every public getter/setter pair and every public field will be
* automatically bound to XML, unless annotated by {@link XmlTransient}.
*
* Fields or getter/setter pairs that are private, protected, or
* defaulted to package-only access are bound to XML only when they are
* explicitly annotated by the appropriate JAXB annotations.
*/
PUBLIC_MEMBER,
/**
* None of the fields or properties is bound to XML unless they
* are specifically annotated with some of the JAXB annotations.
*/
NONE
}
当然JAXB也支持修改XML文档的根节点名称和命名空间,修改方式如下
@XmlRootElement(name="userwy", namespace="user-wy")
2、@XmlAccessorType
POJO:
package org.wy.pojo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class User {
private String name = "wy";
private String sex = "man";
public int age = 20;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
输出结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user><name>wy</name></user>
20
将@XmlAccessorType(XmlAccessType.FIELD)
输出结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user><name>wy</name><sex>man</sex><age>20</age></user>
23
3、@XmlJavaTypeAdapter
复杂对象
POJO:
package org.wy.pojo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class User {
private String name = "wy";
private String sex = "man";
public int age = 20;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlJavaTypeAdapter(AddressAdapter.class)
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address.java接口
package org.wy.pojo;
public interface Address {
public String getAddress();
}
AddressImpl.java
package org.wy.pojo;
public class AddressImpl implements Address{
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
AddressAdapter.java
package org.wy.pojo;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class AddressAdapter extends XmlAdapter<String, Address> {
@Override
public Address unmarshal(String v) throws Exception {
AddressImpl address = new AddressImpl();
address.setAddress(v);
return address;
}
@Override
public String marshal(Address v) throws Exception {
return v.getAddress();
}
}
JaxbTest.java
package org.wy.jaxb;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.wy.pojo.AddressImpl;
import org.wy.pojo.User;
public class JaxbTest {
public static void main(String[] args) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(User.class);
//JavaObject ---> XML
Marshaller marshaller = context.createMarshaller();
User user = new User();
AddressImpl address = new AddressImpl();
address.setAddress("BeiJing");
user.setAddress(address);
marshaller.marshal(user, System.out);
System.out.println();
// XML---> JavaObject
Unmarshaller unmarshaller = context.createUnmarshaller();
String str = "<user><age>23</age></user>";
user = (User)unmarshaller.unmarshal(new StringReader(str));
System.out.println(user.age);
}
}
输出结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user><address>BeiJing</address><name>wy</name></user>
20