先说下这个的背景吧,前些日子,有个以前的小同事说刚接触webservice,想解析下xml,记得我学的时候还是dom4j,sax的解析方式,最近看别人的代码用的jaxb的方式,觉得注解起来很简练,所以就拿jaxb试着写了一个,并一起总结一下,当做备忘录吧。
先看下xml的格式吧,如下
PLANING_RECEIPTS
发送方海关十位数编码
业务编码
业务类型
申报类型
备注
计划入库单编号
账册编号
关区代码
企业海关十位编码
企业名称
毛重
净重
件数
包装种类
申报关区
厂商编码
业务类别
6
8
4
5
3
2
9
7
1
6
8
4
5
3
2
9
7
1
View Code
java解析类,如下
public classTestClass {public static voidmain(String[] args) {
StringBuffer buffer= null;
JAXBContext jaxbContext;try{//读入xml文件流
InputStream is = new FileInputStream(new File("E:\\github\\myproject\\myweb\\src\\main\\resources\\test.xml"));
BufferedReader in= new BufferedReader(newInputStreamReader(is));
buffer= newStringBuffer();
String line= "";while ((line = in.readLine()) != null) {
buffer.append(line);
}//加载映射bean类
jaxbContext = JAXBContext.newInstance(BaseBean.class);//创建解析
Unmarshaller um =jaxbContext.createUnmarshaller();
StreamSource streamSource= new StreamSource(newStringReader(buffer.toString()));
BaseBean root=(BaseBean) um.unmarshal(streamSource);
System.out.println(root);
}catch(Exception e) {
e.printStackTrace();
}
}
}
View Code
其中涉及的javabean相对多一点,就不在这贴了,一样这种日常的东西还是会放到github下,当做自己的积累吧,有兴趣可以down下来看看。
在这里说一下主要的注解,建议没接触过的拿着代码对应着看:
1.XmlRootElement
此注解是一个类级别注解,主要属性为name,看名字也很清楚就是根节点的注解可以指定为根节点的名字
2.XmlType
此注解主要属性为propOrder,可以按指定的顺序生成元素,且指定的顺序必须为全部元素,否则是会报错的
3.XmlElement
此注解主要属性为name,主要用于改变bean属性与xml映射的名字,此注解的包为
javax.xml.bind.annotation,还有个包有相同的注解,用时需加注意。
lax属性可能也需要,当设置lax为true时,可以把xsi:type, xmlns:xs等相关内容去掉
4.XmlAttribute
此注解主要属性为name,主要作用是可以把bean的属性映射为xml
5.XmlAccessorType
此注解用于指定由java对象生成xml文件时对java对象属性的访问方式
XmlAccessType.FIELD:java对象中的所有成员变量
XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量
XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量
XmlAccessType.NONE:java对象的所有属性都不映射为xml的元素
6.XmlAccessorOrder
用于对java对象生成的xml元素进行排序。其value属性,它有两个属性值:
XmlAccessOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
XmlAccessOrder.UNDEFINED:不排序
7.XmlTransient
用于标示在由java对象映射xml时,忽略此属性
8.XmlElementWrapper
表示生成一个包装 XML 表示形式的包装器元素。 此元素主要用于生成一个包装集合的包装器 XML 元素。
注:@XmlElementWrapper仅允许出现在集合属性上。
9.XmlJavaTypeAdapter
常用在转换比较复杂的对象时,用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法
最后把测试上述注解的代码放到这,可以跑一下,就全清楚了,里面还接了放泛型的相关内容
@XmlRootElement(name = "address")
//@XmlType(propOrder = {"name", "code"})
//@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(value = XmlAccessOrder.ALPHABETICAL)
public class TestAddress {
/** code */
private int code;
/** company */
private String name;
/** des */
private String des;
private String xxxx;
private Date nowDate;
private T body;
@XmlElementWrapper(name = "listTest")
@XmlElement(name = "list123")
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
private List list;
/**
* @return 获取 code属性值
*/
public int getCode() {
return code;
}
/**
* @param code 设置 code 属性值为参数值 code
*/
@XmlElement(name = "code1")
public void setCode(int code) {
this.code = code;
}
/**
* @return 获取 name属性值
*/
public String getName() {
return name;
}
/**
* @param name 设置 name 属性值为参数值 name
*/
public void setName(String name) {
this.name = name;
}
@XmlAttribute(name = "desProperty")
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
@XmlTransient
public String getXxxx() {
return xxxx;
}
public void setXxxx(String xxxx) {
this.xxxx = xxxx;
}
public Date getNowDate() {
return nowDate;
}
@XmlJavaTypeAdapter(value = DateAdapter.class)
public void setNowDate(Date nowDate) {
this.nowDate = nowDate;
}
public T getBody() {
return body;
}
@XmlAnyElement(lax=true)
public void setBody(T t) {
this.body = t;
}
@Override
public String toString() {
return "TestAddress{" +
"code=" + code +
", name='" + name + '\'' +
", des='" + des + '\'' +
", xxxx='" + xxxx + '\'' +
", nowDate=" + nowDate +
", body=" + body +
", list=" + list +
'}';
}
}
@XmlRootElement(name = "body")
@XmlAccessorType(XmlAccessType.FIELD)public classJaxbBean {privateString bean1;privateString bean2;publicString getBean1() {returnbean1;
}public voidsetBean1(String bean1) {this.bean1 =bean1;
}publicString getBean2() {returnbean2;
}public voidsetBean2(String bean2) {this.bean2 =bean2;
}
@OverridepublicString toString() {return "JaxbBean{" +
"bean1='" + bean1 + '\'' +
", bean2='" + bean2 + '\'' +
'}';
}
}
public classOXMapper {/**Marshaller*/
privateMarshaller marshaller;/**Unmarshaller*/
privateUnmarshaller unmarshaller;/***@return获取 marshaller属性值*/
publicMarshaller getMarshaller() {returnmarshaller;
}/***@parammarshaller 设置 marshaller 属性值为参数值 marshaller*/
public voidsetMarshaller(Marshaller marshaller) {this.marshaller =marshaller;
}/***@return获取 unmarshaller属性值*/
publicUnmarshaller getUnmarshaller() {returnunmarshaller;
}/***@paramunmarshaller 设置 unmarshaller 属性值为参数值 unmarshaller*/
public voidsetUnmarshaller(Unmarshaller unmarshaller) {this.unmarshaller =unmarshaller;
}/*** 将对象转换输出为xml文件
*
*@paramobject object 对象
*@paramfilename filename 文件名
*@throwsIOException IOException IO异常*/
public void writeObjectToXml(Object object, String filename) throwsIOException {
FileOutputStream fos= null;try{
fos= newFileOutputStream(filename);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(object,newStreamResult(fos));
}catch(JAXBException e) {//LOG.error("Xml-Serialization failed due to an XmlMappingException.", e);
} catch(IOException e) {//LOG.error("Xml-Serialization failed due to an IOException.", e);
} finally{if (fos != null) {
fos.close();
}
}
}/*** 将xml文件转换成java对象
*
*@paramfilename filename 文件名称
*@returnObject 转换后的java对象
*@throwsIOException IOException IO异常
*@throwsJAXBException JAXBException JAXB异常*/
public Object readObjectFromXml(String filename) throwsIOException, JAXBException {
FileInputStream fis= null;try{
fis= newFileInputStream(filename);return unmarshaller.unmarshal(newStreamSource(fis));
}catch(IOException e) {//LOG.error("Xml-Deserialization failed due to an IOException.", e);
} finally{if (fis != null) {
fis.close();
}
}return null;
}/*** 测试用例
*
*@paramargs 传入参数
*@throwsIOException IOException
*@throwsJAXBException JAXBException*/
public static void main(String[] args) throwsIOException, JAXBException {
JaxbBean jaxbBean= newJaxbBean();
jaxbBean.setBean1("124");
jaxbBean.setBean2("456");//TestAddress address = new TestAddress();
address.setCode(58888);
address.setName("深圳市福田区莲花路2075号香丽大厦首层");
address.setDes("测试属性");
address.setXxxx("xxxx");
address.setNowDate(newDate());
List list1 = new ArrayList();
list1.add("test1");
list1.add("test2");
address.setList(list1);
address.setBody(jaxbBean);
JAXBContext objJaxbContext=JAXBContext.newInstance(address.getClass(), jaxbBean.getClass());
Marshaller objMarshaller=objJaxbContext.createMarshaller();
OXMapper oxMapper= newOXMapper();
oxMapper.setMarshaller(objMarshaller);
oxMapper.writeObjectToXml(address,"address.xml");
System.out.println("bean转xml结束");
Unmarshaller objUnmarshaller=objJaxbContext.createUnmarshaller();
oxMapper.setUnmarshaller(objUnmarshaller);
TestAddress objAddress= (TestAddress) oxMapper.readObjectFromXml("address.xml");
System.out.println(objAddress);//System.out.println(ReflectionToStringBuilder.toString(objAddress, ToStringStyle.MULTI_LINE_STYLE));
}
}
参考