zoukankan      html  css  js  c++  java
  • XStream 1.4.10版本处理xml使用问题

    XStream pom依赖:

    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.4.10</version>
    </dependency>    

    1、对象解析成xml字符串时下划线变成双下划线

    解决:

    xStream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_")));

    或者

    xStream = new XStream(new Xpp3Driver(new NoNameCoder()));

    2、Security framework of XStream not initialized, XStream is probably vulnerable

    解决:

    XStream.setupDefaultSecurity(xStream);
    xStream.allowTypesByWildcard(new String[] {
          "com.common.util.**"  //你的包路径
    });

    3、处理既有属性又有值的情况

    形如:<Query Code="1">select * from user</Query>

    使用自定义转换器实现,如下:

    public class QueryConverter implements Converter {
        @Override
        public boolean canConvert(Class type) {
            return type.equals(Query.class);
        }
    
        /**
         * 将java对象转为xml时使用
         */
        @Override
        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
            Query query = (Query) source;
            // 设置属性值
            writer.addAttribute("Code", query.getCode());
            // 设置文本值
            writer.setValue(query.getText());
        }
    
        /**
         * 将xml转为java对象使用
         */
        @Override
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
            Query query = new Query();
            query.setTransactionCode(reader.getAttribute("Code"));
            query.setText(reader.getValue());
            return query;
        }
    }

    之后通过注解@XStreamConverter(value = QueryConverter.class)

    或代码注册转换器使用:

    xStream.registerConverter(new xxxConverter());

    4、时间转换器

    字段为Date类型

    public class DateConverter implements Converter {
    
        @Override
        public boolean canConvert(Class arg0) {
            return Date.class == arg0;
        }
    
        @Override
        public void marshal(Object arg0, HierarchicalStreamWriter arg1, MarshallingContext arg2) {
        }
    
        @Override
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext arg1) {
    
            GregorianCalendar calendar = new GregorianCalendar();
            //格式化当前系统日期
            SimpleDateFormat dateFm = new SimpleDateFormat("yyyy-MM-dd");
            try {
                calendar.setTime(dateFm.parse(reader.getValue()));
            } catch (ParseException e) {
                throw new ConversionException(e.getMessage(), e);
            }
    
            return calendar.getTime();
        }
    }

    使用:

    @XStreamConverter(DateConverter.class)
    private Date beginTime;

    属性为Date类型处理SingleValueConverter 

    public class XStreamDateConverter implements SingleValueConverter {
    
        @Override
        public boolean canConvert(Class arg0) {
            return Date.class == arg0;
        }
    
        @Override
        public Object fromString(String arg0) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                return format.parse(arg0);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public String toString(Object arg0) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                return format.format((Date) arg0);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
    
    }

    之后将转化加在Date属性的字段上使用即可

    @XStreamConverter(value=XStreamDateConverter.class)
    @XStreamAsAttribute
    private Date beginTime;

    5、针对null值的字段也显示在xml中处理

    大概思路就是遍历对象的所有的字段,若当前字段的值为null,则处理成空字符串,示例自定义转换器如下:

    public class FieldConverter implements Converter {
    
        /**
         * 日志记录
         */
        private static final Logger LOGGER = LoggerFactory.getLogger(FieldConverter.class);
    
        /**
         * 时间格式
         */
        private String formatPattern;
    
        public FieldConverter() {
        }
    
        public FieldConverter(String formatPattern) {
            this.formatPattern = formatPattern;
        }
    
        @Override
        public boolean canConvert(Class type) {
            return true;
        }
    
        /**
         * 将java对象转为xml时使用
         */
        @Override
        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
            try {
                handleSource(source, writer);
            } catch (Exception e) {
                LOGGER.error("[FieldConverter] marshal 异常,{}", e);
                throw new IllegalArgumentException("转换xml出错");
            }
        }
    
        /**
         * @description :处理对象为xml转换
         * @param source 对象源
         * @param writer 流写出对象
         * @date  2019/9/29 18:48
         * @modifier
         * @return  void
         */
        private void handleSource(Object source, HierarchicalStreamWriter writer) throws IllegalAccessException {
    
            try {
                Class<?> aClass = source.getClass();
                Field[] declaredFields = aClass.getDeclaredFields();
                for (Field currField : declaredFields) {
                    currField.setAccessible(Boolean.TRUE);
                    // 字段注解
                    boolean isAttr = currField.isAnnotationPresent(XStreamAsAttribute.class);
                    boolean isXStreamAlias = currField.isAnnotationPresent(XStreamAlias.class);
                    boolean isFieldValue = currField.isAnnotationPresent(FieldValue.class);
    
                    // 当前字段值
                    Object curFieldValue = currField.get(source);
    
                    // 字段别名
                    String xmlAlias;
                    if (isXStreamAlias) {
                        xmlAlias = currField.getAnnotation(XStreamAlias.class).value();
                    } else {
                        xmlAlias = currField.getName();
                    }
    
                    if (isAttr) {
                        // 字段属性
                        writer.addAttribute(xmlAlias, null == curFieldValue ? "" : String.valueOf(curFieldValue));
                    } else if (isFieldValue) {
                        // 字段值
                        writer.setValue(String.valueOf(curFieldValue));
                    } else {
                        // 字段简单处理
                        boolean isBaseType = DomainUtil.isBaseType(currField.getType());
                        if (curFieldValue instanceof List) {
                            List<Object> list = (List<Object>) curFieldValue;
                            for (int i = 0; i < list.size(); i++) {
                                writer.startNode(xmlAlias + i);
                                Object curr = list.get(i);
                                isBaseType = DomainUtil.isBaseType(curr.getClass());
                                if (null == curr || isBaseType) {
                                    writer.setValue(null == curr ? "" : String.valueOf(curr));
                                } else {
                                    handleSource(curr, writer);
                                }
                                writer.endNode();
                            }
                        } else {
                            // 开始节点
                            writer.startNode(xmlAlias);
    
                            if (null == curFieldValue || isBaseType) {
                                writer.setValue(null == curFieldValue ? "" : String.valueOf(curFieldValue));
                            } else if (currField.getType().equals(Date.class)) { //时间对象
                                SimpleDateFormat format = new SimpleDateFormat(formatPattern);
                                writer.setValue(null == curFieldValue ? "" : format.format(curFieldValue));
                            } else { //对象类型
                                handleSource(curFieldValue, writer);
                            }
    
                            // 结束节点
                            writer.endNode();
                        }
                    }
                }
            } catch (Exception e) {
                LOGGER.error("[FieldConverter] handleSource 异常,{}", e);
                throw e;
            }
        }
    
        /**
         * 将xml转为java对象使用
         */
        @Override
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
            System.out.println("coming.....");
            return null;
        }

    源码参照 GitHub

  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/kingsonfu/p/11637310.html
Copyright © 2011-2022 走看看