« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9697082 建立时间:2004年12月20日 |

| |
[java语言]正式放弃betwixt使用xstream  原创空间, 文章收藏, 软件技术, 电脑与网络
邢红瑞 发表于 2008/4/5 19:12:45 |
做一个功能很简单的程序,就是将java Object转为xml文件,以前使用apche的digest,觉得使用betwixt应该不会很麻烦,使用前咨询过小叶这些经常使用的高手,建议让我使用xstream,他们也说xstream很快,只是有些小bug,不过我一直不对thoughtworks感兴趣,现在必须改变注意了。实现很简单的功能 1 改变xml根节点 betwixt bw.write(bean.getClass().getSimpleName(), bean);我承认对于 某个类的名字 设定一个xml根节点也不是很复杂。但是 xstream 更舒服 File file = new File("src/test/java/com/jdkcn/test/result.xml");BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));XStream stream = new XStream();stream.alias("result", YupooResult.class);stream.alias("photo",YupooPhoto.class);YupooResult result = (YupooResult)stream.fromXML(reader);2 改变某个节点的名字 例如 <doc> <version>1.0.0</version> <url>doc_url</url> <docName>doc_name</docName> </doc> 变为<doc> <version>1.0.0</version> <contentUrl>doc_url</contentUrl> <docName>doc_name</docName> </doc> 建立一个.betwixt <?xml version="1.0" encoding="UTF-8" ?> <info primitiveTypes="element"> <element name="docResource"> <element name="contentUrl" property="url" /> <addDefaults /> </element> </info> 但是使用Converter 可以容易做到,类似于拦截器,betwixt的ObjectStringConverter只是用于所有日期转为某种格式这样的操作。例如这段代码package net.firsov.xstreamattributes;
/** * */import com.thoughtworks.xstream.*;import com.thoughtworks.xstream.annotations.*;import com.thoughtworks.xstream.converters.*;import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;import com.thoughtworks.xstream.core.JVM;import com.thoughtworks.xstream.io.*;import com.thoughtworks.xstream.io.xml.*;import java.util.*;import java.lang.reflect.*;import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })@interface IntRange { int min(); int max(); }
@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })@interface FieldName{ public String value(); }
@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })@interface FieldDescription{ String value(); }
class AllTypes{
@FieldDescription("This is int field") @FieldName( "Integer Field" ) @IntRange(min=0,max=10) int intField = -1;
@FieldName( "Boolean Field" ) @FieldDescription("This is boolean field") boolean booleanField = true;
double doubleField = 9.99; @FieldName( "String array" ) @FieldDescription("Just some strings") String[] StringArray = {"Hello", "World!"}; String stringField = "Some string\nWith second line";
@FieldName( "Calendar" ) @FieldDescription("GregorianCalendar") Calendar calField = new GregorianCalendar();
}
/** * to be overriden for add custom attributes to XML * @note aware of case, when field reflected in XML as attribute **/ abstract class PreprocessingListener { protected PreprocessingListener(){} protected void PreProcessObject( final Object original , final HierarchicalStreamWriter writer , final MarshallingContext context ){}
protected void PreProcessField( final Field field , final HierarchicalStreamWriter writer , final MarshallingContext context , Object newObj ){} } class PreprocessingConverter extends ReflectionConverter { private List< PreprocessingListener > Listeners = new ArrayList(1); //new HashSet<PreprocessingListener>(); public PreprocessingConverter( XStream xstream ) { super( xstream.getMapper(), new JVM().bestReflectionProvider() ); xstream.registerConverter( this, XStream.PRIORITY_VERY_LOW ); } public < T extends PreprocessingListener > PreprocessingConverter Register( Class<T> listenerClass ) throws InstantiationException, IllegalAccessException { for( PreprocessingListener l: Listeners ) if( l.getClass() == listenerClass ) // listener class already exist return this; // just ignore it
PreprocessingListener listener = listenerClass.newInstance(); Listeners.add( listener ); return this; }
public PreprocessingConverter Register( PreprocessingListener listener ) { Listeners.add( listener ); return this; } public < T extends PreprocessingListener > T CreateLookup( Class<T> listenerClass ) throws InstantiationException, IllegalAccessException { for( PreprocessingListener l: Listeners ) if( l.getClass() == listenerClass ) // listener class already exist return (T)l; // just ignore it
T listener = listenerClass.newInstance(); Listeners.add( listener ); return listener; }
/** inherited methods *************************************************/ transient private HierarchicalStreamWriter _writer = null; public void marshal( Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) { this._writer = writer; for( PreprocessingListener l: Listeners ) l.PreProcessObject( original, writer, context ); super.marshal(original, writer, context); this._writer = null; }
synchronized // to protect _writer protected void marshallField( final MarshallingContext context, Object newObj, Field field ) { for( PreprocessingListener l: Listeners ) l.PreProcessField( field, _writer, context, newObj ); super.marshallField( context, newObj, field ); } }
/** * Add type attribute with field/object class/type to XML. * @todo TBD. shall we use class name alias mapping? Short class name? * **/
class Type2AttribListener extends PreprocessingListener { String TypeAttributeName = "type"; // class name of field/class public Type2AttribListener() { super(); } public Type2AttribListener( String typeAttributeName ) { super(); this.TypeAttributeName = typeAttributeName ; }
protected void PreProcessObject( final Object original , final HierarchicalStreamWriter writer , final MarshallingContext context ) { writer.addAttribute( TypeAttributeName, original.getClass().getName() ); } protected void PreProcessField( final Field field , final HierarchicalStreamWriter writer , final MarshallingContext context , Object newObj ) { writer.addAttribute( TypeAttributeName, field.getType().getName() ); } }
class Annotation2AttribListener extends PreprocessingListener { boolean XsInAttr = false;// is XStream annotations used as XML attributes String TypeAttributeName = "type"; // class name of field/class Annotation[] AnnInAttr = {}; public Annotation2AttribListener() {} static <T> boolean IsObjInArray( T obj, T[] arr ) { for( T a: arr ) if( obj == a ) return true; return false; } // TBD use either annotationType() (full annotation class name) or annotationType().getSimpleName() protected void preProcess( final HierarchicalStreamWriter writer, Class classOrField, Annotation[] annotations ) { for( Annotation a : annotations ) {// if( IsObjInArray( a, AnnInAttr ) ) // break; Method[] mm = a.annotationType().getDeclaredMethods(); for( Method m : mm ) { try { Object s = m.invoke(a); if( mm.length ==1 && "value".equals( m.getName() ) ) writer.addAttribute( a.annotationType().getSimpleName(), ""+s ); else writer.addAttribute( a.annotationType().getSimpleName()+"."+m.getName(), ""+s ); }catch( Exception e) { e.printStackTrace(); } } } } protected void PreProcessObject( final Object original , final HierarchicalStreamWriter writer , final MarshallingContext context ) { preProcess( writer, original.getClass(), original.getClass().getAnnotations() ); } protected void PreProcessField( final Field field , final HierarchicalStreamWriter writer , final MarshallingContext context , Object newObj ) { preProcess( writer, field.getType(), field.getAnnotations() ); } }
public class Main{ public static void main(String[] args) { XStream xstream = new XStream( new DomDriver() ); // does not require XPP3 library xstream.alias("AllTypes", AllTypes.class ); new PreprocessingConverter( xstream ) .Register( new Type2AttribListener() ) // JDK 1.3 is OK .Register( new Annotation2AttribListener() ); // only in 1.5
AllTypes o = new AllTypes(); String xml = xstream.toXML(o);
System.out.println(xml);
o.intField = 10; o.StringArray[1]="Sun";
xstream.fromXML(xml,o); System.out.println( xstream.toXML(o) ); }}本文章思路和代码均来自网上,没有用于启明星辰的任何产品。 |
|
回复:正式放弃betwixt使用xstream 原创空间, 文章收藏, 软件技术, 电脑与网络
裴(游客)发表评论于2009/2/12 11:29:50 |
新的版本已经不需要这样实现了,
http://topic.csdn.net/u/20090212/10/99f3152f-e5f4-4a26-a803-40eb3aa984a0.html
xstream处理根节点内容才叫难你可以看看这个 |
|
» 1 »
|