博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
xstream使用的第二个小问题
阅读量:6820 次
发布时间:2019-06-26

本文共 2934 字,大约阅读时间需要 9 分钟。

hot3.png

之前说过一个xstream使用过程中遇到的一个小问题,链接:

这次又遇到一个,情况是这样的:

当在生产环境使用xstream进行解析xml转换为java对象的时候有一个缓存问题, 如果有两个不相干的接口,这两个接口唯一的共同点就是使用了xstream解析返回结果,且巧合的是两个接口的返回结果xml格式一模一样。

xml结果格式如下:

true

这两个接口都定义了一个bean,且结构一样,A对象定义如下:

@XStreamAliasType(value="response")public class Response1 {       @XStreamAsAttribute    private String success;    @XStreamAsAttribute    private String errorMsg;    public String getSuccess() {        return success;    }    public void setSuccess(String success) {        this.success = success;    }    public String getErrorMsg() {        return errorMsg;    }    public void setErrorMsg(String errorMsg) {        this.errorMsg = errorMsg;    }}

B对象定义如下:

@XStreamAliasType(value="response")public class Response2 {       @XStreamAsAttribute    private String success;    @XStreamAsAttribute    private String errorMsg;    public String getSuccess() {        return success;    }    public void setSuccess(String success) {        this.success = success;    }    public String getErrorMsg() {        return errorMsg;    }    public void setErrorMsg(String errorMsg) {        this.errorMsg = errorMsg;    }}

解析的操作大致如下:

public static void main(String[] args) throws InterruptedException {    String resp = "
true
"; Response1 response1 = (Response1) XmlUtil.xml2Object(resp, new Class[] { Response1.class }); String a = response1.getSuccess(); Object object = XmlUtil.xml2Object(resp, new Class[] { Response2.class }); Response2 response2 = (Response2) object; String b = response2.getSuccess(); System.out.println(a+ " : " +b);}

xmlUtil:

public class XmlUtil {	public static Object xml2Object(String inputXml, Class
[] types){ if (StringUtils.isBlank(inputXml)) { return null; } XStream xstream = XStreamUtil.getInstance(); xstream.processAnnotations(types); return xstream.fromXML(inputXml); }}

当A对象和B对象都在从xml解析到对象的时候会引发一个错误:

com.xxx.Response2 cannot be cast to com.xxx.Response1

根本原因: XStream本身在进行讲xml转换到对象的时候,对每一次操作的类都进行了对象缓存,存储在一个map里面,这个map的key是你要解析的xml的头结点名字,在这里就是response, 当解析xml的时候会读取这个map里面的key为response的value,这样可以直接在缓存里面拿到class,达到解析速度更快。 这就是报错的根本原因。

xstream里的com.thoughtworks.xstream.mapper.CachingMapper类源码是这样定义的:

private transient Map realClassCache;public Class realClass(String elementName) {    Object cached = realClassCache.get(elementName);    if (cached != null) {        if (cached instanceof Class) {            return (Class)cached;        }        throw (XStreamException)cached;    }    try {        Class result = super.realClass(elementName);        realClassCache.put(elementName, result);        return result;    } catch (ForbiddenClassException e) {        realClassCache.put(elementName, e);        throw e;    } catch (CannotResolveClassException e) {        realClassCache.put(elementName, e);        throw e;    }}

可以看出使用 elementName 做缓存,这一点我个人觉得还是有待商榷,为了性能埋下了一个坑。

转载于:https://my.oschina.net/110NotFound/blog/3031869

你可能感兴趣的文章