通用xml转Object 记录

通用xml转Object 记录

直接上代码,基于dom4j解析xml转obj

package com.baiyang.oms.modular.ningpocang.util;

import com.baiyang.oms.modular.ningpocang.model.response.QueryInventoryResp;
import org.apache.commons.beanutils.PropertyUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * 说明:XML工具类
 *
 * @author:wangjunpeng
 * @Date:2018/12/20
 */
public class XmlUtil {

    /**
     * 通用返回响应实体
     * 基于 dom4j
     *
     * @param xmlStr
     * @param <T>
     * @return
     */
    public static <T> T xmlToObject(String xmlStr, Class<T> t) {
        System.out.println(xmlStr);
        try {
            Document doc = DocumentHelper.parseText(xmlStr);
            // 解析第一层跟目录-mo层
            Element element = doc.getRootElement();
            return analyzeXml(t, element);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 递归解析xml
     * 支持List
     *
     * @param t
     * @param el
     * @return
     */
    private static <T> T analyzeXml(Class<T> t, Element el) throws Exception {
        T tt = t.newInstance();
        Iterator it = el.elementIterator();
        while (it.hasNext()) {
            Element el2 = (Element) it.next();
            String name = el2.getName();
            String text = el2.getText();
            Class<?> childClazz = PropertyUtils.getPropertyType(tt, name);
            if (childClazz == null) continue;
            if (List.class.getTypeName().equals(childClazz.getName())) {
                Field field = searchFields(getAllFields(tt), name);
                Type type = field.getGenericType();
                if (type == null) continue;
                // 如果是泛型参数的类型
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    //得到泛型里的class类型对象
                    Class<?> genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
                    List<?> list = parseXml2List(el2, genericClazz);
                    PropertyUtils.setProperty(tt, name, list);
                }
                continue;
            }
            Object child = childClazz.newInstance();
            if (!(child instanceof String)) {
                child = analyzeXml(childClazz, el2);
                PropertyUtils.setProperty(tt, name, child);
            } else {
                PropertyUtils.setProperty(tt, name, text);
            }
        }
        return tt;
    }

    /**
     * 解析xml中List
     *
     * @param el
     * @param cls
     * @return
     * @throws Exception
     */
    private static List<?> parseXml2List(Element el, Class<?> cls) throws Exception {
        List<Object> lists = new ArrayList<>();
        Iterator it = el.elementIterator();
        while (it.hasNext()) {
            Element el2 = (Element) it.next();
            String name = el2.getName();
            String text = el2.getText();
            Object obj = analyzeXml(cls, el2);
            lists.add(obj);
        }
        return lists;
    }

    /**
     * 获取所有一个对象类中以及父类中的属性信息
     *
     * @param object
     * @return
     */
    private static Field[] getAllFields(Object object) {
        Class clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

    /**
     * 查询所有filed中指定name
     *
     * @param fields 所有对象属性数组
     * @param name   变量名
     * @return
     */
    private static Field searchFields(Field[] fields, String name) {
        String internedName = name.intern();
        for (int i = 0; i < fields.length; i++) {
            if (fields[i].getName() == internedName) {
                return fields[i];
            }
        }
        return null;
    }

    public static void main(String[] args) {
        String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<response>\n" +
                "     <flag>success|failure</flag>\n" +
                "     <code>响应码</code>\n" +
                "     <message>响应信息</message>\n" +
                "     <items> \n" +
                "          <item> \n" +
                "               <warehouseCode>仓库编码, string (50) </warehouseCode>  \n" +
                "               <itemCode>商品编码, string (50) , 必填</itemCode>  \n" +
                "               <itemId>仓储系统商品ID, string (50),条件必填</itemId>  \n" +
                "               <inventoryType>库存类型,string (50) , ZP=正品, CC=残次,JS=机损, XS= 箱损, ZT=在途库存</inventoryType>  \n" +
                "               <quantity>正品实物在库库存量,int,必填</quantity> \n" +
                "               <lockQuantity>冻结库存数量,int,必填 </lockQuantity>\n" +
                "               <batchCode>批次编码, string (50) </batchCode>  \n" +
                "               <productDate>商品生产日期 YYYY-MM-DD</productDate>  \n" +
                "               <expireDate>商品过期日期YYYY-MM-DD</expireDate>  \n" +
                "               <produceCode>生产批号, string (50) </produceCode>  \n" +
                "               <extendProps>扩展属性 \n" +
                "                       <key1>value1</key1>  \n" +
                "                       <key2>value2</key2> \n" +
                "               </extendProps> \n" +
                "          </item> \n" +
                "     </items> \n" +
                "</response>\n";
        QueryInventoryResp resp = xmlToBaseResponse(xml, QueryInventoryResp.class);
        System.out.println(resp.toString());
    }

}

QueryInventoryResp 实体类代码

package com.baiyang.oms.modular.ningpocang.model.response;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;

import java.util.List;

/**
 * 说明:库存查询返回实体
 *
 * @author:wangjunpeng
 * @Date:2018/12/21
 */
@Data
@XStreamAlias("response")
public class QueryInventoryResp {
	/**
     * success|failure
     */
    private String flag;
    /**
     * 返回状态码
     */
    private String code;
    /**
     * 返回状态描述
     */
    private String message;
    
    List<QueryInventoryItem> items;
}

QueryInventoryItem 实体

package com.baiyang.oms.modular.ningpocang.model.response;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;

import java.util.Map;

/**
 * 说明:库存信息
 *
 * @author:wangjunpeng
 * @Date:2018/12/21
 */
@Data
@XStreamAlias("item")
public class QueryInventoryItem {

    /**
     * 仓库编码
     */
    private String warehouseCode;
    /**
     * 商品编码
     */
    private String itemCode;
    /**
     * 仓储系统商品ID
     */
    private String itemId;
    /**
     * 库存类型,string (50) , ZP=正品, CC=残次,JS=机损, XS= 箱损, ZT=在途库存
     */
    private String inventoryType;
    /**
     * 正品实物在库库存量
     */
    private String quantity;
    /**
     * 冻结库存数量
     */
    private String lockQuantity;
    /**
     * 批次编码
     */
    private String batchCode;
    /**
     * 商品生产日期 YYYY-MM-DD
     */
    private String productDate;
    /**
     * 商品过期日期YYYY-MM-DD
     */
    private String expireDate;
    /**
     * 生产批号, string (50)
     */
    private String produceCode;

//    /**
//     * 扩展属性
//     */
//    private Map<String, String> extendProps;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值