java 利用Xstream生成和解析xml,知识结构:
1.Xstream简介;
2.Xstream注解常用知识:
@XStreamAlias("message") 别名注解
作用目标: 类,字段
@XStreamImplicit 隐式集合
@XStreamImplicit(itemFieldName="part")
作用目标: 集合字段
@XStreamConverter(SingleValueCalendarConverter.class) 注入转换器
作用目标: 对象
@XStreamAsAttribute 转换成属性
作用目标: 字段
@XStreamOmitField 忽略字段
作用目标: 字段
Auto-detect Annotations 自动侦查注解
xstream.autodetectAnnotations(true);
自动侦查注解与XStream.processAnnotations(Class[] cls)的区别在于性能.自动侦查注解将缓存所有类的类型.
3.案例分析: (1)同一标签下多个同名元素;
(2)同一标签下循环多个对象;
1.Xstream简介;
使用限制: JDK版本不能<1.5.
虽然预处理注解是安全的,但自动侦查注解可能发生竞争条件.
特点:
简化的API;
无映射文件;
高性能,低内存占用;
整洁的XML;
不需要修改对象;支持内部私有字段,不需要setter/getter方法,final字段;非公有类,内部类;类不需要默认构造器,完全对象图支持.维护对象引用计数,循环引用. i
提供序列化接口;
自定义转换类型策略;
详细的错误诊断;
快速输出格式;当前支持 JSON 和 morphing.
使用场景
Transport 转换
Persistence 持久化对象
Configuration 配置
Unit Tests 单元测
隐式集合
当我们使用集合类时不想显示集合,只显示里面的元素即可.
使用隐式集合前:
<list>
<element />
<element />
<list>
使用隐式集合:
xstream.addImplicitCollection(Person.class, "list");
使用隐式集合后:
<element />
<element />
2.Xstream注解常用知识:
@XStreamAlias("message") 别名注解
作用目标: 类,字段
@XStreamImplicit 隐式集合
@XStreamImplicit(itemFieldName="part")
作用目标: 集合字段
@XStreamConverter(SingleValueCalendarConverter.class) 注入转换器
作用目标: 对象
@XStreamAsAttribute 转换成属性
作用目标: 字段
@XStreamOmitField 忽略字段
作用目标: 字段
Auto-detect Annotations 自动侦查注解
xstream.autodetectAnnotations(true);
自动侦查注解与XStream.processAnnotations(Class[] cls)的区别在于性能.自动侦查注解将缓存所有类的类型.
3.案例分析: (1)同一标签下多个同名元素;
(2)同一标签下循环多个对象;
标签:
XStream
代码片段(12) [全屏查看所有代码]
1. [代码]1.实体类:PersonBean
01 | import java.util.List; |
02 |
03 | import com.thoughtworks.xstream.annotations.XStreamAlias; |
04 | import com.thoughtworks.xstream.annotations.XStreamImplicit; |
05 |
06 | /** |
07 | *@ClassName:PersonBean |
08 | *@author: chenyoulong Email: chen.youlong@payeco.com |
09 | *@date :2012-9-28 下午3:10:47 |
10 | *@Description:TODO |
11 | */ |
12 | @XStreamAlias("person") |
13 | public class PersonBean { |
14 | @XStreamAlias("firstName") |
15 | private String firstName; |
16 | @XStreamAlias("lastName") |
17 | private String lastName; |
18 | |
19 | @XStreamAlias("telphone") |
20 | private PhoneNumber tel; |
21 | @XStreamAlias("faxphone") |
22 | private PhoneNumber fax; |
23 | |
24 | //测试一个标签下有多个同名标签 |
25 | @XStreamAlias("friends") |
26 | private Friends friend; |
27 | |
28 | //测试一个标签下循环对象 |
29 | @XStreamAlias("pets") |
30 | private Pets pet; |
31 | |
32 | |
33 | //省略setter和getter |
34 | } |
2. [代码]2.实体类:PhoneNumber
01 | @XStreamAlias("phoneNumber") |
02 | public class PhoneNumber{ |
03 | @XStreamAlias("code") |
04 | private int code; |
05 | @XStreamAlias("number") |
06 | private String number; |
07 | |
08 | //省略setter和getter |
09 | |
10 | } |
3. [代码]3.实体类:Friends(一个标签下有多个同名标签 )
01 | /** |
02 | * 用Xstream注解的方式实现:一个标签下有多个同名标签 |
03 | *@ClassName:Friends |
04 | *@author: chenyoulong Email: chen.youlong@payeco.com |
05 | *@date :2012-9-28 下午4:32:24 |
06 | *@Description:TODO 5个name 中国,美国,俄罗斯,英国,法国 |
07 | *http://blog.youkuaiyun.com/menhuanxiyou/article/details/5426765 |
08 | */ |
09 | public static class Friends{ |
10 | @XStreamImplicit(itemFieldName="name") //itemFieldName定义重复字段的名称, |
11 | /*<friends> <friends> |
12 | <name>A1</name> <String>A1</String> |
13 | <name>A2</name> 如果没有,则会变成 =====> <String>A1</String> |
14 | <name>A3</name> <String>A1</String> |
15 | </friends> </friends> |
16 | */ |
17 | private List<String> name; |
18 |
19 | public List<String> getName() { |
20 | return name; |
21 | } |
22 |
23 | public void setName(List<String> name) { |
24 | this.name = name; |
25 | } |
26 | } |
4. [代码]4.1实体类:Animal(同一标签下循环对象实体1)
01 | //测试同一标签下循环某一对象 |
02 | public class Animal{ |
03 | @XStreamAlias("name") |
04 | private String name; |
05 | @XStreamAlias("age") |
06 | private int age; |
07 | public Animal(String name,int age){ |
08 | this.name=name; |
09 | this.age=age; |
10 | } |
11 | |
12 | //省略setter和getter |
13 | } |
14 | |
5. [代码]4.2实体类:Pets(同一标签下循环对象实体2)
01 | /** |
02 | * 测试同一标签下循环某一对象 |
03 | *@ClassName:Pets |
04 | *@author: chenyoulong Email: chen.youlong@payeco.com |
05 | *@date :2012-9-28 下午6:26:01 |
06 | *@Description:TODO |
07 | */ |
08 | public class Pets{ |
09 | @XStreamImplicit(itemFieldName="pet") |
10 | private List<Animal> animalList; |
11 | |
12 | public List<Animal> getAnimalList() { |
13 | return animalList; |
14 | } |
15 |
16 | public void setAnimalList(List<Animal> animalList) { |
17 | this.animalList = animalList; |
18 | } |
19 | |
20 | } |
6. [代码]5.main函数示例1:toxml
01 | import com.thoughtworks.xstream.XStream; |
02 | import com.thoughtworks.xstream.io.json.JsonWriter.Format; |
03 | import com.thoughtworks.xstream.io.xml.DomDriver; |
04 |
05 | /** |
06 | *@ClassName:PersonTest |
07 | *@author: chenyoulong |
08 | *@date :2012-9-28 下午3:25:09 |
09 | *@Description:TODO |
10 | */ |
11 | public class PersonTest { |
12 |
13 | /** |
14 | * @Title: main |
15 | * @Description: TODO |
16 | * @param args |
17 | * @return void |
18 | */ |
19 | public static void main(String[] args) { |
20 | // TODO Auto-generated method stub |
21 | |
22 | PersonBean per=new PersonBean(); |
23 | per.setFirstName("chen"); |
24 | per.setLastName("youlong"); |
25 | |
26 | PhoneNumber tel=new PhoneNumber(); |
27 | tel.setCode(137280); |
28 | tel.setNumber("137280968"); |
29 | |
30 | PhoneNumber fax=new PhoneNumber(); |
31 | fax.setCode(20); |
32 | fax.setNumber("020221327"); |
33 | per.setTel(tel); |
34 | per.setFax(fax); |
35 | |
36 | |
37 | //测试一个标签下有多个同名标签 |
38 | List<String> friendList=new ArrayList<String>(); |
39 | friendList.add("A1"); |
40 | friendList.add("A2"); |
41 | friendList.add("A3"); |
42 | Friends friend1=new Friends(); |
43 | friend1.setName(friendList); |
44 | per.setFriend(friend1); |
45 | |
46 | //测试一个标签下循环对象 |
47 | Animal dog=new Animal("Dolly",2); |
48 | Animal cat=new Animal("Ketty",2); |
49 | List<Animal> petList=new ArrayList<Animal>(); |
50 | petList.add(dog); |
51 | petList.add(cat); |
52 | Pets pet=new Pets(); |
53 | pet.setAnimalList(petList); |
54 | per.setPet(pet); |
55 | |
56 | //java对象转换成xml |
57 | String xml=XmlUtil.toXml(per); |
58 | System.out.println("xml==="+xml); |
59 | |
60 | } |
61 | } |
7. [代码]xml效果图
01 | xml===<person> |
02 | <firstName>chen</firstName> |
03 | <lastName>youlong</lastName> |
04 | <telphone> |
05 | <code>137280</code> |
06 | <number>137280968</number> |
07 | </telphone> |
08 | <faxphone> |
09 | <code>20</code> |
10 | <number>020221327</number> |
11 | </faxphone> |
12 | <friends> |
13 | <name>A1</name> |
14 | <name>A2</name> |
15 | <name>A3</name> |
16 | </friends> |
17 | <pets> |
18 | <pet> |
19 | <name>doly</name> |
20 | <age>2</age> |
21 | </pet> |
22 | <pet> |
23 | <name>Ketty</name> |
24 | <age>2</age> |
25 | </pet> |
26 | </pets> |
27 | </person> |
8. [代码]5.2 main函数示例2:toBean
01 | public static void main(String[] args) { |
02 | // TODO Auto-generated method stub |
03 | |
04 | //toXml |
05 | // String xmlStr=new PersonTest().toXml(); |
06 | |
07 | //toBean |
08 | // PersonBean per=new PersonTest().toBean(); |
09 | String xmlStr="<person>"+ |
10 | "<firstName>chen</firstName>"+ |
11 | "<lastName>youlong</lastName>"+ |
12 | "<telphone>"+ |
13 | "<code>137280</code>"+ |
14 | "<number>137280968</number>"+ |
15 | "</telphone>"+ |
16 | "<faxphone>"+ |
17 | "<code>20</code>"+ |
18 | "<number>020221327</number>"+ |
19 | "</faxphone>"+ |
20 | "<friends>"+ |
21 | "<name>A1</name>"+ |
22 | "<name>A2</name>"+ |
23 | "<name>A3</name>"+ |
24 | "</friends>"+ |
25 | "<pets>"+ |
26 | "<pet>"+ |
27 | "<name>doly</name>"+ |
28 | "<age>2</age>"+ |
29 | "</pet>"+ |
30 | "<pet>"+ |
31 | "<name>Ketty</name>"+ |
32 | "<age>2</age>"+ |
33 | "</pet>"+ |
34 | "</pets>"+ |
35 | "</person>"; |
36 | //用泛型的知识 |
37 | PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class); |
38 | System.out.println("person=firstname=="+person.getFirstName()); |
39 | System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0)); |
40 | System.out.println("person==Pets==name2=="+person.getPet().getAnimalList().get(1).getName()); |
41 |
42 | /* |
43 | //效果与以下方法类同,(以下代码较为直观) |
44 | XStream xstream=new XStream(new DomDriver()); //注意:不是new Xstream(); 否则报错: |
45 |
46 | xstream.processAnnotations(PersonBean.class); |
47 | PersonBean person=(PersonBean)xstream.fromXML(xmlStr); |
48 | System.out.println("person=firstname=="+person.getFirstName()); |
49 | System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0)); |
50 | System.out.println("person==Pets==name=="+person.getPet().getAnimalList().get(1).getName()); |
51 | */ |
52 |
53 | |
54 | } |
9. [代码]6.XmlUtil工具类(toxml()和toBean())
001 | /** |
002 | * 输出xml和解析xml的工具类 |
003 | *@ClassName:XmlUtil |
004 | *@author: chenyoulong Email: chen.youlong@payeco.com |
005 | *@date :2012-9-29 上午9:51:28 |
006 | *@Description:TODO |
007 | */ |
008 | public class XmlUtil{ |
009 | /** |
010 | * java 转换成xml |
011 | * @Title: toXml |
012 | * @Description: TODO |
013 | * @param obj 对象实例 |
014 | * @return String xml字符串 |
015 | */ |
016 | public static String toXml(Object obj){ |
017 | XStream xstream=new XStream(); |
018 | // XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom来解释 |
019 | // XStream xstream=new XStream(new DomDriver("utf-8")); //指定编码解析器,直接用jaxp dom来解释 |
020 | |
021 | ////如果没有这句,xml中的根元素会是<包.类名>;或者说:注解根本就没生效,所以的元素名就是类的属性 |
022 | xstream.processAnnotations(obj.getClass()); //通过注解方式的,一定要有这句话 |
023 | return xstream.toXML(obj); |
024 | } |
025 | |
026 | /** |
027 | * 将传入xml文本转换成Java对象 |
028 | * @Title: toBean |
029 | * @Description: TODO |
030 | * @param xmlStr |
031 | * @param cls xml对应的class类 |
032 | * @return T xml对应的class类的实例对象 |
033 | * |
034 | * 调用的方法实例:PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class); |
035 | */ |
036 | public static <T> T toBean(String xmlStr,Class<T> cls){ |
037 | //注意:不是new Xstream(); 否则报错:java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory |
038 | XStream xstream=new XStream(new DomDriver()); |
039 | xstream.processAnnotations(cls); |
040 | T obj=(T)xstream.fromXML(xmlStr); |
041 | return obj; |
042 | } |
043 |
044 | /** |
045 | * 写到xml文件中去 |
046 | * @Title: writeXMLFile |
047 | * @Description: TODO |
048 | * @param obj 对象 |
049 | * @param absPath 绝对路径 |
050 | * @param fileName 文件名 |
051 | * @return boolean |
052 | */ |
053 | |
054 | public static boolean toXMLFile(Object obj, String absPath, String fileName ){ |
055 | String strXml = toXml(obj); |
056 | String filePath = absPath + fileName; |
057 | File file = new File(filePath); |
058 | if(!file.exists()){ |
059 | try { |
060 | file.createNewFile(); |
061 | } catch (IOException e) { |
062 | log.error("创建{"+ filePath +"}文件失败!!!" + Strings.getStackTrace(e)); |
063 | return false ; |
064 | } |
065 | }// end if |
066 | OutputStream ous = null ; |
067 | try { |
068 | ous = new FileOutputStream(file); |
069 | ous.write(strXml.getBytes()); |
070 | ous.flush(); |
071 | } catch (Exception e1) { |
072 | log.error("写{"+ filePath +"}文件失败!!!" + Strings.getStackTrace(e1)); |
073 | return false; |
074 | }finally{ |
075 | if(ous != null ) |
076 | try { |
077 | ous.close(); |
078 | } catch (IOException e) { |
079 | log.error("写{"+ filePath +"}文件关闭输出流异常!!!" + Strings.getStackTrace(e)); |
080 | } |
081 | } |
082 | return true ; |
083 | } |
084 | |
085 | /** |
086 | * 从xml文件读取报文 |
087 | * @Title: toBeanFromFile |
088 | * @Description: TODO |
089 | * @param absPath 绝对路径 |
090 | * @param fileName 文件名 |
091 | * @param cls |
092 | * @throws Exception |
093 | * @return T |
094 | */ |
095 | public static <T> T toBeanFromFile(String absPath, String fileName,Class<T> cls) throws Exception{ |
096 | String filePath = absPath +fileName; |
097 | InputStream ins = null ; |
098 | try { |
099 | ins = new FileInputStream(new File(filePath )); |
100 | } catch (Exception e) { |
101 | throw new Exception("读{"+ filePath +"}文件失败!", e); |
102 | } |
103 | |
104 | String encode = useEncode(cls); |
105 | XStream xstream=new XStream(new DomDriver(encode)); |
106 | xstream.processAnnotations(cls); |
107 | T obj =null; |
108 | try { |
109 | obj = (T)xstream.fromXML(ins); |
110 | } catch (Exception e) { |
111 | // TODO Auto-generated catch block |
112 | throw new Exception("解析{"+ filePath +"}文件失败!",e); |
113 | } |
114 | if(ins != null) |
115 | ins.close(); |
116 | return obj; |
117 | } |
118 | |
119 | } |
本文介绍Java库XStream用于对象与XML之间的转换。包括XStream的特点、使用限制及常见注解,通过具体代码示例展示了如何处理复杂对象结构,如同一标签下的多个同名元素和循环对象。
2987

被折叠的 条评论
为什么被折叠?



