java中XStream处理xml数据

java中XStream处理xml数据,第1张

java中XStream处理xml数据 java中XStream处理xml数据

文章目录
  • 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:序列化为xml
2.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依赖

    org.projectlombok
    lombok


    com.thoughtworks.xstream
    xstream
    1.4.11.1
    compile

3.2 创建XStream对象

创建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 List teachers;
}

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输出:
  001
  
    中华小学
    chengdu
  
  
    
      lin
      math
    
    
      liu
      english
    
  

格式化xml输出:
  001
  
    中华小学
    chengdu
  
  
    
      lin
      math
    
    
      liu
      english
    
  

XStream的driver为StaxDriver(此时存在字段单下划线被转为双下划线问题,如下面字段stu__no ,可以通过字符串替换xml.replaceAll("__", “_”)解决)输出结果为:

原始xml输出:001中华小学chengdulinmathliuenglish
格式化xml输出:
  001
  
    中华小学
    chengdu
  
  
    
      lin
      math
    
    
      liu
      english
    
  

四、更多

XStream还可以自定义转化器,在此略过。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5582640.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存