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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM