java 利用Xstream註解生成和解析xml
1.Xstream簡介;
使用限制: JDK版本不能<1.5.
雖然預處理註解是安全的,但自動偵查註解可能發生競爭條件.
特點:
簡化的API;
無對映檔案;
高效能,低記憶體佔用;
整潔的XML;
不需要修改物件;支援內部私有欄位,不需要setter/getter方法,final欄位;非公有類,內部類;類不需要預設構造器,完全物件圖支援.維護物件引用計數,迴圈引用. i
提供序列化介面;
自定義轉換型別策略;
詳細的錯誤診斷;
快速輸出格式;當前支援 JSON 和 morphing.
使用場景
Transport 轉換
Persistence 持久化物件
Configuration 配置
Unit Tests 單元測
2.Xstream註解常用知識:
@XStreamAlias(“message”) 別名註解
作用目標: 類,欄位
@XStreamImplicit 隱式集合
@XStreamImplicit(itemFieldName=”part”)
作用目標: 集合欄位
@XStreamConverter(SingleValueCalendarConverter.class) 注入轉換器
作用目標: 物件
@XStreamAsAttribute 轉換成屬性
作用目標: 欄位
@XStreamOmitField 忽略欄位
作用目標: 欄位
Auto-detect Annotations 自動偵查註解
xstream.autodetectAnnotations(true);
自動偵查註解與XStream.processAnnotations(Class[] cls)的區別在於效能.自動偵查註解將快取所有類的型別.
1. [程式碼]1.實體類:PersonBean
import java.util.List;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
@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. [程式碼]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
*@Description:TODO 5個name 中國,美國,俄羅斯,英國,法國
*http://blog.csdn.net/menhuanxiyou/article/details/5426765
*/
public static class Friends{
@XStreamImplicit(itemFieldName="name") //itemFieldName定義重複欄位的名稱,
/*<friends> <friends>
<name>A1</name> <String>A1</String>
<name>A2</name> 如果沒有,則會變成 =====> <String>A1</String>
<name>A3</name> <String>A1</String>
</friends> </friends>
*/
private List<String> name;
public List<String> getName() {
return name;
}
public void setName(List<String> 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
*@Description:TODO
*/
public class Pets{
@XStreamImplicit(itemFieldName="pet")
private List<Animal> animalList;
public List<Animal> getAnimalList() {
return animalList;
}
public void setAnimalList(List<Animal> 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
*@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<String> friendList=new ArrayList<String>();
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<Animal> petList=new ArrayList<Animal>();
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===<person>
<firstName>chen</firstName>
<lastName>youlong</lastName>
<telphone>
<code>137280</code>
<number>137280968</number>
</telphone>
<faxphone>
<code>20</code>
<number>020221327</number>
</faxphone>
<friends>
<name>A1</name>
<name>A2</name>
<name>A3</name>
</friends>
<pets>
<pet>
<name>doly</name>
<age>2</age>
</pet>
<pet>
<name>Ketty</name>
<age>2</age>
</pet>
</pets>
</person>
8. [程式碼]5.2 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="<person>"+
"<firstName>chen</firstName>"+
"<lastName>youlong</lastName>"+
"<telphone>"+
"<code>137280</code>"+
"<number>137280968</number>"+
"</telphone>"+
"<faxphone>"+
"<code>20</code>"+
"<number>020221327</number>"+
"</faxphone>"+
"<friends>"+
"<name>A1</name>"+
"<name>A2</name>"+
"<name>A3</name>"+
"</friends>"+
"<pets>"+
"<pet>"+
"<name>doly</name>"+
"<age>2</age>"+
"</pet>"+
"<pet>"+
"<name>Ketty</name>"+
"<age>2</age>"+
"</pet>"+
"</pets>"+
"</person>";
//用泛型的知識
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. [程式碼]6.XmlUtil工具類(toxml()和toBean())
/**
* 輸出xml和解析xml的工具類
*@ClassName:XmlUtil
*@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> T toBean(String xmlStr,Class<T> 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> T toBeanFromFile(String absPath, String fileName,Class<T> 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;
}
}