- java中XStream处理xml数据
- 一、简介
- 二、使用
- 2.1 XStream对象
- 2.1.1 创建XStream对象
- 2.1.2 XStream常用driver
- 2.1.3 XStream属性
- 2.2 常用注解
- 2.3 XStream转换方法
- 2.4 格式化xml字符串
- 三、示例
- 3.1 添加maven依赖
- 3.2 创建XStream对象
- 3.3 创建bean类
- 3.4 测试
- 四、更多
XStream是java类库,可以将java对象序列化为xml(或json)或反序列化为java对象。
二、使用 2.1 XStream对象在进行序列化前,先创建XStream对象,创建成功后不必重复创建(由于创建XStream会消耗大量资源,故大量创建XStream会存在性能问题),后续可复用,且XStream对象是线程安全。
2.1.1 创建XStream对象通过new方法即可简单创建XStream对象
public class XStreamFactory { //初始化XStream对象,后续直接复用该对象(创建XStream对象开销大,大量重复创建会引发性能问题),Xstream是多线程安全的 //DomDriver类型 // private static XStream instance = new XStream(new DomDriver("UTF-8")); //Xpp3Driver不会出现字段单下划线被转为双下划线问题 // private static XStream instance = new XStream(new Xpp3Driver(new NonameCoder())); //StaxDriver类型 private static XStream instance = new XStream(new StaxDriver()); //获取XStream实例 public static XStream getXStreamInstance() { return instance; } }2.1.2 XStream常用driver
XStream对象初始化时需指定driver,XStream的driver有各种类型,常用的有:
JettisonMappedXmlDriver:依赖jettison库,可以obj转json, json转obj StaxDriver:序列化为xml DomDriver:序列化为xml JsonHierarchicalStreamDriver:不依赖其他库, obj转json StaxDriver:序列化为xml2.1.3 XStream属性
XStream对象初始化时可指定属性,常用属性有:
权限设置:可设置为最低,如:xStream.addPermission(AnyTypePermission.ANY); 设置是否注解解析:true是,false否,如:xStream.autodetectAnnotations(true); 引用设置:如存在引用时, 设置无引用模式xStream.setMode(XStream.NO_REFERENCES); 忽略未知元素:如 instance.ignoreUnknownElements();2.2 常用注解
@XStreamAlias: 指定别名,不使用注解时采用字段原始名称, 等价于:xStream.alias方法 @XStreamAsAttribute:指定以属性方式显示, 等价于:xStream.aliasField方法 @XStreamOmitField:xml忽略字段,等价于:xStream.omitField方法 @XStreamConverter:设置转换器, 等价于:xStream.registerConverter方法 @XStreamConverters:设置转换器 @XStreamImplicit:属性是数组或列表,不显示array或list字样, 等价于:xStream.addImplicitCollection方法2.3 XStream转换方法
toXML方法:序列化对象; fromXML方法:反序列化对象;2.4 格式化xml字符串
借助javax.xml.transform.Transformer类(SAXTransformerFactory.newInstance().newTransformer())可以格式化xml字符串,常用属性有:
设置缩进(yes:有缩进 no:没有缩进): 如transformer.setOutputProperty(OutputKeys.INDENT, "yes"), 设置编码:如transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 设置是否忽略xml声明(yes:忽略 no:不忽略):如transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 设置缩进字符数(仅在设置需要缩进时有效):如transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");三、示例 3.1 添加maven依赖
3.2 创建XStream对象org.projectlombok lombokcom.thoughtworks.xstream xstream1.4.11.1 compile
创建XStream对象工具类,使用getXStreamInstance获取XStream实例
import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.StaxDriver; import com.thoughtworks.xstream.security.AnyTypePermission; import org.xml.sax.InputSource; import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.stream.StreamResult; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; public class XStreamFactory { //初始化XStream对象,后续直接复用该对象(创建XStream对象开销大,大量重复创建会引发性能问题),Xstream是多线程安全的 //DomDriver类型 // private static XStream instance = new XStream(new DomDriver("UTF-8")); //Xpp3Driver不会出现字段单下划线被转为双下划线问题 private static XStream instance = new XStream(new Xpp3Driver(new NoNameCoder())); //StaxDriver类型 //private static XStream instance = new XStream(new StaxDriver()); static { //设置权限为最低 instance.addPermission(AnyTypePermission.ANY); //开启注解解析 instance.autodetectAnnotations(true); //存在引用时, 设置无引用模式 instance.setMode(XStream.NO_REFERENCES); //忽略未知元素 instance.ignoreUnknownElements(); } //获取XStream实例 public static XStream getXStreamInstance() { return instance; } //格式化xml字符串 public static String formatXml(String xml){ try{ Transformer transformer = SAXTransformerFactory.newInstance().newTransformer(); //设置缩进, yes:有缩进 no:没有缩进 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //设置编码 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //设置是否忽略xml声明, yes:忽略 no:不忽略 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); //设置缩进字符数,仅在设置需要缩进时有效 transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); Source xmlSource = new SAXSource(new InputSource(new ByteArrayInputStream(xml.getBytes()))); StreamResult res = new StreamResult(new ByteArrayOutputStream()); transformer.transform(xmlSource, res); xml = new String(((ByteArrayOutputStream) res.getOutputStream()).toByteArray()); }catch (Exception e){ } return xml; } }3.3 创建bean类
Teacher类
import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor @XStreamAlias("teacher") public class Teacher { private String name; private String course; }
TeacherItem类
import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamImplicit; import lombok.*; import java.util.List; @Data @Builder @NoArgsConstructor @AllArgsConstructor @XStreamAlias("teachers") public class TeacherItem { //@Singular可对集合内单个元素增加或删除 @Singular //@XStreamImplicit表示不显示集合标签 @XStreamImplicit private Listteachers; }
School类
import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor @XStreamAlias("school") public class School { private String name; private String address; }
Stu类
import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor @XStreamAlias("stu") public class Stu { //指定别名,默认为相同,不用指定 @XStreamAlias("stu_no") private String no; //以属性方式显示字段 @XStreamAsAttribute private String name; private School school; private TeacherItem teacherItem; }3.4 测试
使用注解进行常规测试
import com.dragon.study.spring_boot_main.xstream.paper.bean.School; import com.dragon.study.spring_boot_main.xstream.paper.bean.Stu; import com.dragon.study.spring_boot_main.xstream.paper.bean.Teacher; import com.dragon.study.spring_boot_main.xstream.paper.bean.TeacherItem; import com.thoughtworks.xstream.XStream; import org.springframework.util.Assert; public class XStreamPaperMain { public static void main(String[] args) { //复用获取XStream实例 XStream xStream = XStreamFactory.getXStreamInstance(); School school = School.builder().name("中华小学").address("chengdu").build(); Teacher teacherOne = Teacher.builder().name("lin").course("math").build(); Teacher teacherTwo = Teacher.builder().name("liu").course("english").build(); TeacherItem teacherItem = TeacherItem.builder().teacher(teacherOne).teacher(teacherTwo).build(); Stu stu = Stu.builder().no("001").name("apple").school(school).teacherItem(teacherItem).build(); String xml = xStream.toXML(stu); //直接转xml输出 System.out.println("原始xml输出:"+xml); //格式化后输出 xml = XStreamFactory.formatXml(xml); System.out.println("格式化xml输出:"+xml); //反序列化为java对象 Stu newStu = (Stu) xStream.fromXML(xml); Assert.notNull(newStu, "not null"); } }
XStream的driver为Xpp3Driver输出结果为:
原始xml输出:格式化xml输出: 001 中华小学 chengdulin math liu english 001 中华小学 chengdulin math liu english
XStream的driver为StaxDriver(此时存在字段单下划线被转为双下划线问题,如下面字段stu__no ,可以通过字符串替换xml.replaceAll("__", “_”)解决)输出结果为:
原始xml输出:四、更多格式化xml输出: 001 中华小学 chengdulin math liu english 001 中华小学 chengdulin math liu english
XStream还可以自定义转化器,在此略过。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)