xstream处理null值属性转换

来源:互联网 发布:java 自定义数据结构 编辑:程序博客网 时间:2024/05/08 14:09

日常使用xstream进行xml转换的时候,会遇到实体对象中有null值的情况,默认的xstream转换遇见null值后不会生成节点xml信息,但是一般为了保证我们xml的可读和完整性,我们希望即使是null值也能够输出节点的xml,废话不说,上干货。

两个实体类:

/** * Project Name:test * File Name:User.java * Package Name:dao * Date:2014-5-16下午5:11:41 * Copyright (c) 2014, renxingchen All Rights Reserved. * */package dao;import java.util.List;import java.util.Set;/** * @ClassName: User * @description: TODO ADD FUNCTION. * @date: 2014-5-16 下午5:11:41 *  * @author renxingchen * @since JDK 1.6 */public class User {public User() {}public User(int id, String name, List<Order> orderList, Order order,Set<Order> orderSet) {super();this.id = id;this.name = name;this.orderList = orderList;this.order = order;this.orderSet = orderSet;}private int id;private String name;private List<Order> orderList;private Order order;private Set<Order> orderSet;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Order getOrder() {return order;}public void setOrder(Order order) {this.order = order;}public List<Order> getOrderList() {return orderList;}public void setOrderList(List<Order> orderList) {this.orderList = orderList;}public Set<Order> getOrderSet() {return orderSet;}public void setOrderSet(Set<Order> orderSet) {this.orderSet = orderSet;}}

/** * Project Name:test * File Name:Order.java * Package Name:dao * Date:2014-5-16下午5:11:41 * Copyright (c) 2014, renxingchen All Rights Reserved. * */package dao;/** * @ClassName: Order * @description: TODO ADD FUNCTION. * @date: 2014-5-16 下午5:13:09 *  * @author renxingchen * @since JDK 1.6 */public class Order {public Order() {}public Order(int id, String orderName) {super();this.id = id;this.orderName = orderName;}private int id;private String orderName;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getOrderName() {return orderName;}public void setOrderName(String orderName) {this.orderName = orderName;}}

自己的xstream转换器,目前可以处理包含Collection集合的对象,如果在实际使用中无法满足需求,可以对marshalSuper这个方法进行拓展即可。

/** * Project Name:test * File Name:MoreDataResultNullConverter.java * Package Name:dao * Date:2014-5-16下午5:11:41 * Copyright (c) 2014, renxingchen All Rights Reserved. * */package dao;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.Arrays;import java.util.Collection;import java.util.List;import java.util.Set;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;/** *  * @ClassName: MoreDataResultNullConverter * @description: 处理含有null值对象的xstream转换器 * @date: 2014-5-19 下午6:05:12 *  * @author renxingchen * @since JDK 1.6 */public class MoreDataResultNullConverter implements Converter {@SuppressWarnings("rawtypes")private Class currentType;private final String clazzNames[] = { "User", "Order" };// 定义所要转换的对象及所包含的对象名称private List<String> clazzNamesList;@SuppressWarnings("rawtypes")@Overridepublic boolean canConvert(Class type) {currentType = type;clazzNamesList = Arrays.asList(clazzNames);if (clazzNamesList.contains(currentType.getSimpleName())) {return true;} else {return false;}}@Overridepublic void marshal(Object source, HierarchicalStreamWriter writer,MarshallingContext context) {try {marshalSuper(source, writer, context, currentType);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}@SuppressWarnings({ "unchecked", "rawtypes" })private Object getObj(Class clazz, String nodeName, Object source)throws Exception {Method method = clazz.getMethod("get"+ Character.toUpperCase(nodeName.substring(0, 1).toCharArray()[0])+ nodeName.substring(1));Object obj = null;obj = method.invoke(clazz.cast(source), new Object[0]);return obj;}@SuppressWarnings({ "rawtypes" })private void objConverter(Object source, HierarchicalStreamWriter writer,MarshallingContext context, Class clazz, String nodeName,Class fieldClazz) throws Exception {Object obj = getObj(clazz, nodeName, source);writer.startNode(nodeName);marshalSuper(obj, writer, context, fieldClazz);writer.endNode();}@SuppressWarnings({ "rawtypes" })private void collectionConverter(Object source,HierarchicalStreamWriter writer, MarshallingContext context,Class clazz, String nodeName, Field field) throws Exception {Type types[] = ((ParameterizedType) field.getGenericType()).getActualTypeArguments();Object obj = getObj(clazz, nodeName, source);Collection collection = null;if (field.getType().equals(List.class)) {collection = (List) obj;} else if (field.getType().equals(Set.class)) {collection = (Set) obj;}writer.startNode(nodeName);for (Object object : collection) {String clazzName = ((Class) types[0]).getSimpleName();writer.startNode(Character.toLowerCase(clazzName.substring(0, 1).toCharArray()[0]) + clazzName.substring(1));marshalSuper(object, writer, context, (Class) types[0]);writer.endNode();}writer.endNode();}@SuppressWarnings({ "rawtypes" })private void basicTypeConverter(Object source,HierarchicalStreamWriter writer, MarshallingContext context,Class clazz, String nodeName) throws Exception {Object obj = getObj(clazz, nodeName, source);writer.startNode(nodeName);writer.setValue(obj == null ? "" : obj.toString());writer.endNode();}@SuppressWarnings({ "rawtypes" })private void marshalSuper(Object source, HierarchicalStreamWriter writer,MarshallingContext context, Class clazz) throws Exception {Field fields[] = clazz.getDeclaredFields();for (Field field : fields) {String nodeName = field.getName();Class fieldClazz = field.getType();if (clazzNamesList.contains(fieldClazz.getSimpleName())) {objConverter(source, writer, context, clazz, nodeName,fieldClazz);} else if (Arrays.asList(fieldClazz.getInterfaces()).contains(Collection.class)) {collectionConverter(source, writer, context, clazz, nodeName,field);} else {basicTypeConverter(source, writer, context, clazz, nodeName);}}}@Overridepublic Object unmarshal(HierarchicalStreamReader reader,UnmarshallingContext context) {// TODO Auto-generated method stubreturn null;}}

最后是测试类:

/** * Project Name:wisdom-tourism * File Name:Demo.java * Package Name:dao * Date:2014-5-16下午5:11:20 * Copyright (c) 2014, renxingchen All Rights Reserved. * */package dao;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;import com.thoughtworks.xstream.XStream;import com.thoughtworks.xstream.io.xml.StaxDriver;/** * ClassName:Demo <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2014-5-16 下午5:11:20 <br/> *  * @author jason * @version * @since JDK 1.6 * @see */public class Demo {public static void main(String[] args) {Order order = new Order(1, null);Order order1 = new Order(2, null);List<Order> orderList = new ArrayList<Order>();Set<Order> orderSet = new HashSet<Order>();orderList.add(order);orderList.add(order1);orderSet.add(order);orderSet.add(order1);User user = new User(1, null, orderList, order, orderSet);XStream xStream = new XStream(new StaxDriver());xStream.alias("user", User.class);xStream.registerConverter(new MoreDataResultNullConverter());String result = xStream.toXML(user);System.err.println(result);}}

测试结果:
<?xml version='1.0' encoding='UTF-8'?><user><id>1</id><name></name><orderList><order><id>1</id><orderName></orderName></order><order><id>2</id><orderName></orderName></order></orderList><order><id>1</id><orderName></orderName></order><orderSet><order><id>1</id><orderName></orderName></order><order><id>2</id><orderName></orderName></order></orderSet></user>
null值属性的节点能够被输出。

仓促写成,应该还有很多问题,如果有疑问请留言交流。

0 0
原创粉丝点击