Spring OXM-XStream注解-CSDN博客

266 阅读3分钟

概述

XStream不但可以通过编程的方式对XML进行转换,而且支持基于注解的方式。

我们先来看下支持的注解

注解说明作用目标
@XStreamAlias别名注解类、字段
@XStreamAsAttribute转换成属性字段
@XStreamOmitField忽略字段字段
@XstreamConverter注入转换器对象
@XstreamImplicit隐式集合集合字段

示例

package com.xgj.oxm.xstream.quickDemo.annotation;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

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

/**
 * 
 * 
 * @ClassName: User
 * 
 * @Description: 使用注解
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年12月6日 下午9:17:11
 */

@XStreamAlias("user")
public class User {

    @XStreamAsAttribute
    @XStreamAlias("userId")
    private int id;

    @XStreamAlias("userName")
    private String userName;

    @XStreamAlias("password")
    private String password;

    @XStreamAlias("credits")
    private int credits;

    @XStreamAlias("lastIp")
    private String lastIp;

    @XStreamConverter(DateConverter.class)
    private Date lastVisit;

    @XStreamImplicit
    private List<LoginLog> logs;

    private Map datas;

    public List<LoginLog> getLogs() {
        return logs;
    }

    public void setLogs(List logs) {
        this.logs = logs;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getCredits() {
        return credits;
    }
    public void setCredits(int credits) {
        this.credits = credits;
    }
    public String getLastIp() {
        return lastIp;
    }
    public void setLastIp(String lastIp) {
        this.lastIp = lastIp;
    }

    public Date getLastVisit() {
        return lastVisit;
    }

    public void setLastVisit(Date lastVisit) {
        this.lastVisit = lastVisit;
    }

    public void addLoginLog(LoginLog log) {
        if (this.logs == null) {
            logs = new ArrayList<LoginLog>();
        }
        logs.add(log);
    }

    public Map getDatas() {
        return datas;

    }

    public void setDatas(Map datas) {
        this.datas = datas;
    }


}
package com.xgj.oxm.xstream.quickDemo.annotation;

import java.io.Serializable;
import java.util.Date;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamConverter;

@XStreamAlias("loginLog")
public class LoginLog implements Serializable {
    private static final long serialVersionUID = 1L;

    @XStreamAsAttribute
    @XStreamAlias("id")
    private int loginLogId;

    @XStreamAsAttribute
    private int userId;

    @XStreamAlias("ip")
    private String ip;

    @XStreamAlias("loginDate")
    @XStreamConverter(DateConverter.class)
    private Date loginDate;

    public int getLoginLogId() {
        return loginLogId;
    }

    public void setLoginLogId(int loginLogId) {
        this.loginLogId = loginLogId;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Date getLoginDate() {
        return loginDate;
    }

    public void setLoginDate(Date loginDate) {
        this.loginDate = loginDate;
    }

}

解读

通过 @XStreamAlias为别名注解,一般用于目标类或者字段,比如 @XStreamAlias(“user”) @XStreamAlias(“userId”)

@XstreamConverter注解用于注入自定义的转换器,比如@XStreamConverter(DateConverter.class)注入一个日期转换器

对于集合类型,可以用@XStreamImplicit注解来隐藏,作用和Stream#addImplicitCollection方法一样。

@XStreamAsAttribute注解将Java对象映射为XML元素的一个属性

@XStreamOmitField注解标注的Java对象将不会出现在XML中。


自定义转换器

package com.xgj.oxm.xstream.quickDemo.annotation;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.thoughtworks.xstream.converters.SingleValueConverter;

public class DateConverter implements SingleValueConverter {

    public DateConverter() {   

    }  

    public String toString(Object obj) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(
                    "yyyy-MM-dd HH:mm:ss");
            dateFormat.setLenient(true);
            return dateFormat.format(((Date)obj));
        } catch (Exception e) {
            return null;
        }
    }

    public Object fromString(String date) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(
                    "yyyy-MM-dd HH:mm:ss");
            dateFormat.setLenient(true);
            return dateFormat.parse(date);
        } catch (Exception e) {
            return null;
        }
    }


    public boolean canConvert(Class type) {
        return type.equals(Date.class);
    }

}

测试类

package com.xgj.oxm.xstream.quickDemo.annotation;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.Date;

import com.thoughtworks.xstream.XStream;

public class Test {
    private static XStream xstream;
    static {
        xstream = new XStream();
        // (1) 第一张方式 手工注册 : 实现该方法,判断要转换的类型
        // xstream.processAnnotations(User.class);
        // xstream.processAnnotations(LoginLog.class);
        // (2) 第二种方法 自动检测 自动加载注解Bean 推荐
        xstream.autodetectAnnotations(true);
    }

    // 初始化转换对象
    public static User getUser() {
        LoginLog log1 = new LoginLog();
        LoginLog log2 = new LoginLog();
        log1.setIp("192.168.1.91");
        log1.setLoginDate(new Date());

        log2.setIp("127.0.0.1");
        log2.setLoginDate(new Date());

        User user = new User();
        user.setId(1);
        user.setUserName("xstream");

        user.addLoginLog(log1);
        user.addLoginLog(log2);

        return user;
    }

    /**
     * JAVA对象转化为XML
     */
    public static void objectToXml() throws Exception {
        User user = getUser();
        FileOutputStream fs = new FileOutputStream(
                "D://XStreamAnnotationSample.xml");
        OutputStreamWriter writer = new OutputStreamWriter(fs,
                Charset.forName("UTF-8"));
        xstream.toXML(user, writer);

        System.out.println("output xml:\n" + xstream.toXML(user));
    }

    /**
     * XML转化为JAVA对象
     */
    public static User xmlToObject() throws Exception {
        FileInputStream fis = new FileInputStream(
                "D://XStreamAnnotationSample.xml");
        InputStreamReader reader = new InputStreamReader(fis,
                Charset.forName("UTF-8"));
        User user = (User) xstream.fromXML(fis);
        for (LoginLog log : user.getLogs()) {
            if (log != null) {
                System.out.println("访问IP: " + log.getIp());
                System.out.println("访问时间: " + log.getLoginDate());
            }
        }
        return user;
    }

    public static void main(String[] args) throws Exception {
        objectToXml();
        xmlToObject();
    }
}

解读

要启用XStream提供的注解功能,需要在执行对象和XML转换之前注册标注了XStream注解的Java对象。 比如

xstream.processAnnotations(User.class);
xstream.processAnnotations(LoginLog.class);

手工注册User和LoginLog对象。

XStream除了手工注册外,还提供了一个自动检测标注了XStream注解的java对象的方法Xstream#autodetectAnnotations(true),不仅方便,而且提供了缓存机制缓存所有标注了XStream注解的Java对象。


运行结果

output xml:
<user userId="1">
  <userName>xstream</userName>
  <credits>0</credits>
  <loginLog id="0" userId="0">
    <ip>192.168.1.91</ip>
    <loginDate>2017-12-07 21:57:52</loginDate>
  </loginLog>
  <loginLog id="0" userId="0">
    <ip>127.0.0.1</ip>
    <loginDate>2017-12-07 21:57:52</loginDate>
  </loginLog>
</user>
Security framework of XStream not initialized, XStream is probably vulnerable.
访问IP: 192.168.1.91
访问时间: Thu Dec 07 21:57:52 CST 2017
访问IP: 127.0.0.1
访问时间: Thu Dec 07 21:57:52 CST 2017

示例源码

代码已托管到Github—> github.com/yangshangwe…