利用Xstream注解实现xml和java bean之间的转换

java 利用Xstream生成和解析xml,知识结构:
1.Xstream简介;

使用限制: JDK版本不能<1.5. 
虽然预处理注解是安全的,但自动侦查注解可能发生竞争条件.

特点: 
简化的API; 
无映射文件; 
高性能,低内存占用; 
整洁的XML; 
不需要修改对象;支持内部私有字段,不需要setter/getter方法,final字段;非公有类,内部类;类不需要默认构造器,完全对象图支持.维护对象引用计数,循环引用. i 
提供序列化接口; 
自定义转换类型策略; 
详细的错误诊断; 
快速输出格式;当前支持 JSON 和 morphing. 

使用场景 
Transport 转换 
Persistence 持久化对象 
Configuration 配置 
Unit Tests 单元测

隐式集合 
当我们使用集合类时不想显示集合,只显示里面的元素即可. 
使用隐式集合前: 
 
  
  
 

使用隐式集合: 
xstream.addImplicitCollection(Person.class, "list"); 

使用隐式集合后: 
  
  


 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.实体类:PersonBean

import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

/**
 *@ClassName:PersonBean
 *@author: chenyoulong  Email: [email protected]
 *@date :2012-9-28 下午3:10:47
 *@Description:TODO 
 */
@XStreamAlias("person")
public class PersonBean {
	@XStreamAlias("firstName")
	private String firstName;
	@XStreamAlias("lastName")
	private String lastName;
	
	@XStreamAlias("telphone")
	private PhoneNumber tel;
	@XStreamAlias("faxphone")
	private PhoneNumber fax;
	
	//测试一个标签下有多个同名标签
	@XStreamAlias("friends")
	private Friends friend;
	
	//测试一个标签下循环对象
	@XStreamAlias("pets")
	private Pets pet;
	
	
	//省略setter和getter
}

2.实体类:PhoneNumber  

@XStreamAlias("phoneNumber")
	public  class PhoneNumber{
		@XStreamAlias("code")
		private int code;
		@XStreamAlias("number")
		private String number;
		
            //省略setter和getter
		
	}


3. [代码]3.实体类:Friends(一个标签下有多个同名标签 )

/**
	 * 用Xstream注解的方式实现:一个标签下有多个同名标签 
	 *@ClassName:Friends
	 *@author: chenyoulong  Email: [email protected]
	 *@date :2012-9-28 下午4:32:24
	 *@Description:TODO 5个name 中国,美国,俄罗斯,英国,法国
	 *http://blog.csdn.net/menhuanxiyou/article/details/5426765
	 */
	public static class Friends{
		@XStreamImplicit(itemFieldName="name")   //itemFieldName定义重复字段的名称,
		/*								
	    	A1							A1
	    	A2    如果没有,则会变成	=====>		A1
	    	A3							A1
	  									
	  */
		private List name;

		public List getName() {
			return name;
		}

		public void setName(List name) {
			this.name = name;
		}
	}

4. [代码]4.1实体类:Animal(同一标签下循环对象实体1)  

//测试同一标签下循环某一对象
	public  class Animal{
		@XStreamAlias("name")
		private String name;
		@XStreamAlias("age")
		private int age;
		public Animal(String name,int age){
			this.name=name;
			this.age=age;
		}
		
              //省略setter和getter
	}
	


5. [代码]4.2实体类:Pets(同一标签下循环对象实体2)  

/**
	 * 测试同一标签下循环某一对象
	 *@ClassName:Pets
	 *@author: chenyoulong  Email: [email protected]
	 *@date :2012-9-28 下午6:26:01
	 *@Description:TODO
	 */
	public class Pets{
		@XStreamImplicit(itemFieldName="pet")
		private List animalList;
		
		public List getAnimalList() {
			return animalList;
		}

		public void setAnimalList(List animalList) {
			this.animalList = animalList;
		}
		
	}


6. [代码]5.main函数示例1:toxml 

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JsonWriter.Format;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 *@ClassName:PersonTest
 *@author: chenyoulong  
 *@date :2012-9-28 下午3:25:09
 *@Description:TODO 
 */
public class PersonTest {

	/** 
	 * @Title: main 
	 * @Description: TODO 
	 * @param args 
	 * @return void  
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		PersonBean per=new PersonBean();
		per.setFirstName("chen");
		per.setLastName("youlong");
		
		PhoneNumber tel=new PhoneNumber();
		tel.setCode(137280);
		tel.setNumber("137280968");
		
		PhoneNumber fax=new PhoneNumber();
		fax.setCode(20);
		fax.setNumber("020221327");
		per.setTel(tel);
		per.setFax(fax);
		
		
		//测试一个标签下有多个同名标签
		List friendList=new ArrayList();
		friendList.add("A1");
		friendList.add("A2");
		friendList.add("A3");
		Friends friend1=new Friends();
		friend1.setName(friendList);
		per.setFriend(friend1);
		
		//测试一个标签下循环对象
		Animal dog=new Animal("Dolly",2);
		Animal cat=new Animal("Ketty",2);
		List petList=new ArrayList();
		petList.add(dog);
		petList.add(cat);
		Pets pet=new Pets();
		pet.setAnimalList(petList);
		per.setPet(pet);
		
                    //java对象转换成xml
		String xml=XmlUtil.toXml(per);
		System.out.println("xml==="+xml);
		
	}
}


7. [代码]xml效果图  

xml===
  chen
  youlong
  
    137280
    137280968
  
  
    20
    020221327
  
  
    A1
    A2
    A3
  
  
    
      doly
      2
    
    
      Ketty
      2
    
  


8 main函数示例2:toBean  

public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//toXml
//		String xmlStr=new PersonTest().toXml();
		
		//toBean
//		PersonBean per=new PersonTest().toBean();
		String xmlStr=""+
				  "chen"+
				  "youlong"+
				  ""+
				    "137280"+
				    "137280968"+
				  ""+
				  ""+
				    "20"+
				    "020221327"+
				  ""+
				  ""+
				    "A1"+
				    "A2"+
				    "A3"+
				  ""+
				  ""+
				    ""+
				      "doly"+
				      "2"+
				    ""+
				    ""+
				      "Ketty"+
				      "2"+
				    ""+
				  ""+
				"";
//用泛型的知识
		PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);
		System.out.println("person=firstname=="+person.getFirstName());
		System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0));
		System.out.println("person==Pets==name2=="+person.getPet().getAnimalList().get(1).getName());

/*
//效果与以下方法类同,(以下代码较为直观)
XStream xstream=new XStream(new DomDriver()); //注意:不是new Xstream(); 否则报错:

		xstream.processAnnotations(PersonBean.class);
		PersonBean person=(PersonBean)xstream.fromXML(xmlStr);
		System.out.println("person=firstname=="+person.getFirstName());
		System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0));
		System.out.println("person==Pets==name=="+person.getPet().getAnimalList().get(1).getName());
*/

		
	}


9. XmlUtil工具类(toxml()和toBean()) 

/**
	 * 输出xml和解析xml的工具类
	 *@ClassName:XmlUtil
	 *@author: chenyoulong  Email: [email protected]
	 *@date :2012-9-29 上午9:51:28
	 *@Description:TODO
	 */
	public class XmlUtil{
		/**
		 * java 转换成xml
		 * @Title: toXml 
		 * @Description: TODO 
		 * @param obj 对象实例
		 * @return String xml字符串
		 */
		public static String toXml(Object obj){
			XStream xstream=new XStream();
//			XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom来解释
//			XStream xstream=new XStream(new DomDriver("utf-8")); //指定编码解析器,直接用jaxp dom来解释
			
			如果没有这句,xml中的根元素会是<包.类名>;或者说:注解根本就没生效,所以的元素名就是类的属性
			xstream.processAnnotations(obj.getClass()); //通过注解方式的,一定要有这句话
			return xstream.toXML(obj);
		}
		
		/**
		 *  将传入xml文本转换成Java对象
		 * @Title: toBean 
		 * @Description: TODO 
		 * @param xmlStr
		 * @param cls  xml对应的class类
		 * @return T   xml对应的class类的实例对象
		 * 
		 * 调用的方法实例:PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);
		 */
		public static  T  toBean(String xmlStr,Class cls){
			//注意:不是new Xstream(); 否则报错:java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory
			XStream xstream=new XStream(new DomDriver());
			xstream.processAnnotations(cls);
			T obj=(T)xstream.fromXML(xmlStr);
			return obj;			
		} 

       /**
	     * 写到xml文件中去
	     * @Title: writeXMLFile 
	     * @Description: TODO 
	     * @param obj 对象
	     * @param absPath 绝对路径
	     * @param fileName	文件名
	     * @return boolean
	     */
	  
	    public static boolean toXMLFile(Object obj, String absPath, String fileName ){
	    	String strXml = toXml(obj);
	    	String filePath = absPath + fileName;
	    	File file = new File(filePath);
	    	if(!file.exists()){
	    		try {
					file.createNewFile();
				} catch (IOException e) {
					log.error("创建{"+ filePath +"}文件失败!!!" + Strings.getStackTrace(e));
					return false ;
				}
	    	}// end if 
	    	OutputStream ous = null ;
			try {
				ous = new FileOutputStream(file);
				ous.write(strXml.getBytes());
				ous.flush();
			} catch (Exception e1) {
				log.error("写{"+ filePath +"}文件失败!!!" + Strings.getStackTrace(e1));
				return false;
			}finally{
				if(ous != null )
					try {
						ous.close();
					} catch (IOException e) {
						log.error("写{"+ filePath +"}文件关闭输出流异常!!!" + Strings.getStackTrace(e));
					}
			}
			return true ;
	    }
	    
	    /**
	     * 从xml文件读取报文
	     * @Title: toBeanFromFile 
	     * @Description: TODO 
	     * @param absPath 绝对路径
	     * @param fileName 文件名
	     * @param cls
	     * @throws Exception 
	     * @return T
	     */
	    public static  T  toBeanFromFile(String absPath, String fileName,Class cls) throws Exception{
	    	String filePath = absPath +fileName;
	    	InputStream ins = null ;
	    	try {
	    		ins = new FileInputStream(new File(filePath ));
			} catch (Exception e) {
				throw new Exception("读{"+ filePath +"}文件失败!", e);
			}
	    	
	    	String encode = useEncode(cls);
			XStream xstream=new XStream(new DomDriver(encode));
			xstream.processAnnotations(cls);
			T obj =null;
			try {
				obj = (T)xstream.fromXML(ins);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				throw new Exception("解析{"+ filePath +"}文件失败!",e);
			}
			if(ins != null)
				ins.close();
			return obj;			
	    } 
		
	}


你可能感兴趣的:(利用Xstream注解实现xml和java bean之间的转换)