最近同事在weblogic8.1下使用xmlbean,中间出现个问题,有个节点存储的内容也是个xml,输出的时候要求用CDATA括起来。
总结下,在weblogic的xmlbean中和apache的xmlbean有几种情况
1)weblogic的xmlbean和apache的xmlbean-1.x:
根据内容的大小和特殊字符的个数有个算法来决定是用CDATA扩起来还是转义
具体的判断在com.bea.xbean.store.Saver$TextSaver和org.apache.xmlbeans.impl.store.Saver$TextSaver里面
if ((this._lastEmitCch > 32) && (count > 5) && (count * 100 / this._lastEmitCch > 1)){ //用<![CDATA[ }else{ //转义 }
其中_lastEmitCch应该是内容的总数量,count是 '<'和'&'的数量
2)在apache的xmlbean-2.x中,估计是意识到了该部分的不可控性,添加了SAVE_CDATA_ENTITY_COUNT_THRESHOLD 、SAVE_CDATA_LENGTH_THRESHOLD 、LOAD_SAVE_CDATA_BOOKMARKS 来控制输出 具体见http://xmlbeans.apache.org/docs/2.4.0/reference/index.html
判断条件也改成了
if (forceCData || (_lastEmitCch > _cdataLengthThreshold && count > _cdataEntityCountThreshold) ) { //用<![CDATA[ }else{ //转义 }
自己想到的一种修改方式:patch Saver类,让他基本按照CDATA输出.
开始的时候尝试反编译Saver改完后再编译。但是各种内部类和jar的引用搞的焦头烂额,
最后采取patch bytecode的方式
原来的是
106: getfield #94; //Field _lastEmitCch:I 109: bipush 32 111: if_icmple 332 114: iload 4 116: iconst_5 117: if_icmple 332 120: iload 4 122: bipush 100 124: imul 125: aload_0 126: getfield #94; //Field _lastEmitCch:I 129: idiv 130: iconst_1 131: if_icmple 332 134: aload_0 135: getfield #99; //Field _buf:[C 138: iload_1 139: caload
最开始想吧131处的改成00,但是报错。。。最后决定改成if_icmple 134
然后把patch后的文件打进jar放到EAR里面。自己测试倒是通过了,但是不知道是否存在jar引用先后顺序的问题。。。。