Android中XStream基础使用

496 阅读1分钟
  • 集成XStream
    implementation 'com.thoughtworks.xstream:xstream:1.4.19'
  • 基础使用

    1.定义实体类

        @XStreamAlias("Document")
        data class WPMLDocument(
            @XStreamAlias("wpml:missionConfig")
            val missionConfig: WPMLMissionConfig,
            @XStreamAlias("Folder")
            val folder: WPMLFolder
        )
    

    2.注解使用

    @XStreamAlias:定义根节点别名与属性别名
    
    @XStreamOmitField:忽略该属性
    
    @XStreamAsAttribute:声明命名空间
    

    3.序列化

    val xStream = XmlUtf8XStream(
            reflectionProvider = PureJavaReflectionProvider(
                FieldDictionary(PartialSeqFieldKeySorter())
            )
        )
        xStream.processAnnotations(WPMLRootElement::class.java)
        return xStream.toXML(this)
    

    4.反序列化

        Class<?>[] classes = new Class[] { TestBody.class};
        val xStream = XStream()
        xStream.allowTypes(classes)//白名单
        xStream.processAnnotations(classes)//开启注解
        val wpml = xStream.fromXML(wpmlFile)
    
  • 疑难问题

    • 按顺序序列化
    @XMLSequence
    
    • 反序列化安全问题:
    com.thoughtworks.xstream.security.ForbiddenClassException com.thoughtworks.xstream
    

    解决方法:添加白名单

    Class<?>[] classes = new Class[] { TestBody.class};
    xStream.allowTypes(classes);
    
    • 反序列化注解不识别:
    com.thoughtworks.xstream.mapper.CannotResolveClassException: xxx
    

    解决方法:反序列化手动开启注解

    xStream.processAnnotations(classes)
    
    • xml文件新增版本号
        class XmlUtf8XStream(version:String="1.0",encoding:String = "UTF-8",reflectionProvider:ReflectionProvider):XStream(reflectionProvider) {
        
            private var version:String
            private var encoding:String
        
            init {
                this.version = version
                this.encoding = encoding
            }
        
            private fun getDeclaration():String {
                return "<?xml version=\"" + this.version + "\" encoding=\"" + this.encoding + "\"?>\n"
            }
        
            override fun toXML(obj: Any?, out: OutputStream?) {
                val dec = getDeclaration()
                val bytesOfDec = dec.toByteArray(charset("UTF-8"))
                out?.write(bytesOfDec)
                super.toXML(obj, out)
            }
        
            override fun toXML(obj: Any?, out: Writer?) {
                out?.write(getDeclaration())
                super.toXML(obj, out)
            }
    }