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

  • 相关阅读:
    狗蛋带仨妞【Beta】Scrum meeting 1
    实验九 团队作业5:团队项目编码与Alpha冲刺
    狗蛋带仨妞【Alpha】Scrum meeting 7
    狗蛋带仨妞【Alpha】Scrum meeting 6
    狗蛋带仨妞【Alpha】Scrum meeting 5
    狗蛋带仨妞 【Alpha】Scrum meeting 1-4
    Rosetta中准备配体的参数文件
    pymol安装
    chemshell的creation之后
    关于KIE的一点认识
  • 原文地址:https://www.cnblogs.com/kingsonfu/p/11637310.html
Copyright © 2011-2022 走看看