使用中需要注意的问题:
1.java对象的字段如果有下划线xstream转成xml时会变成双下划线,解决办法:
XStream xs = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_")));
2.xstream默认的时间串格式较少,在默认不满足的情况下,需要自己实现Converter接口,并注册到xstream中
3.在java对象比较复杂的情况下,为了代码组织方便,使用静态内部类是个好办法。注:使用普通内部类转换后的xml会生成依赖声明
package com.iteye.am-human.message.msgDefinition; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; import com.thoughtworks.xstream.io.xml.XppDriver; /** * 消息结构的抽象基类 * * @author Wuyc * */ public abstract class BaseMsg { public BaseMsg(){} public BaseMsg(Head head) { super(); this.head = head; } public BaseMsg(int commandId){ super(); this.head = new Head(commandId,getSequence()); } private Head head; public Head getHead() { return head; } public void setHead(Head head) { this.head = head; } /** * 将当前对象转换成xml数据 * * @return xml数据 */ public String toXml(){ XStream xs = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_"))); xs.autodetectAnnotations(true); return xs.toXML(this); } protected static String getSequence(){ return "1"+Math.round(Math.random()*10e14); } }
package com.iteye.am-human.message.msgDefinition; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.io.xml.DomDriver; /** * <xmp> * <?xml version="1.0" encoding="UTF-8" ?> * <root> * <head> * <command>5011</command> * <sequence>编号</sequence> * </head> * <body> * <data> * <flow_list> * <flow> * <flow_instance_id></flow_instance_id> * <flow_status></flow_status> * <flow_start_time></flow_start_time> * <srv_list> * <service> * <service_id></service_id> * <proc_list> * <proc> * <proc_id></proc_id> * <pid></pid> * <vm_id></vm_id> * <handle_count></handle_count> * <handle_speed></handle_speed> * <proc_start_time></proc_start_time> * </proc> * </proc_list> * </service> * </srv_list> * </flow> * </flow_list> * </data> * </body> * </root> * </xmp> * * @author Wuyc * */ @XStreamAlias("root") public class Msg5011Def extends BaseMsg { private static final int COMMAND_ID = 5011; private Body body; public Msg5011Def(){ super(COMMAND_ID); this.body = new Body(); } public static Msg5011Def fromXml(String xml){ XStream xstream = new XStream(new DomDriver()); xstream.alias("root",Msg5011Def.class); xstream.alias("flow",Msg5011Def.Body.Data.Flow.class); xstream.alias("service",Msg5011Def.Body.Data.Flow.Service.class); xstream.alias("proc",Msg5011Def.Body.Data.Flow.Service.Process.class); xstream.registerConverter(new DateSingleValueConverter()); return (Msg5011Def)xstream.fromXML(xml); } public static class Body extends BaseBody{ private Data data; public Body(){ this.data = new Data(); } public static class Data{ private List<Flow> flow_list; public Data(){ this.flow_list = new ArrayList<Flow>(); } @XStreamAlias("flow") public static class Flow{ private int flow_instance_id; private int flow_status; private Date flow_start_time; private List<Service> srv_list; public Flow(){ this.srv_list = new ArrayList<Service>(); } @XStreamAlias("service") public static class Service{ private int service_id; private List<Process> proc_list; public Service(){ this.proc_list = new ArrayList<Process>(); } @XStreamAlias("proc") public static class Process{ private int proc_id; private int pid; private int vm_id; private int handle_count; // 当天的处理量 private float handle_speed; // 处理速度 private Date proc_start_time; // 进程启动时间 public int getProc_id() { return proc_id; } public int getPid() { return pid; } public int getVm_id() { return vm_id; } public int getHandle_count() { return handle_count; } public float getHandle_speed() { return handle_speed; } public Date getProc_start_time() { return proc_start_time; } } public int getService_id() { return service_id; } public List<Process> getProc_list() { return proc_list; } } public int getFlow_instance_id() { return flow_instance_id; } public int getFlow_status() { return flow_status; } public List<Service> getSrv_list() { return srv_list; } public Date getFlow_start_time() { return flow_start_time; } } public List<Flow> getFlow_list() { return flow_list; } } public Data getData() { return data; } } public Body getBody() { return body; } }
package com.iteye.am-human.message.msgDefinition; import java.util.Date; import java.text.ParseException; import java.text.SimpleDateFormat; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; /** * Date数据转换器 * 默认的format格式为:yyyyMMddHHmmss * * @author Wuyc * */ public class DateSingleValueConverter implements Converter { private SimpleDateFormat sdf; public DateSingleValueConverter(){ this.sdf = new SimpleDateFormat("yyyyMMddHHmmss"); } public DateSingleValueConverter(String formatString){ this.sdf = new SimpleDateFormat(formatString); } public void marshal(Object arg0, HierarchicalStreamWriter writer, MarshallingContext arg2) { Date date = (Date)arg0; writer.setValue(sdf.format(date)); } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext arg1) { Date date = null; try { String strDate = reader.getValue(); if(strDate != null && strDate.length()!=0 && !"".equals(strDate) && !"0".equals(strDate)){ date = sdf.parse(reader.getValue()); } } catch (ParseException e) { e.printStackTrace(); } return date; } public boolean canConvert(Class type) { return Date.class.equals(type); } }
其他的xml转换框架:
castor
官网: http://www.castor.org/
通过定义mapping文件,实现xml和javabean的对应。
JOX
官网: http://www.wutka.com/jox.html
sourceforge(官网打不开): http://sourceforge.net/projects/jox/