XStream导出xml文件

最终效果

pom依赖

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

代码

XStreamUtil

这个直接复制即可


import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.thoughtworks.xstream.io.xml.XppDriver;

import java.io.Writer;
import java.lang.reflect.Field;

public class XStreamUtil {

    public static XStream getXStream(Class<?> targetClass,Class<?> targetClass2) {

        XStream stream =  new XStream(new XppDriver() {
            @Override
            public HierarchicalStreamWriter createWriter(Writer out) {
                return new PrettyPrintWriter(out) {
                    // 对所有xml节点的转换都增加CDATA标记
                    boolean cdata = false;

                    @Override
                    @SuppressWarnings("rawtypes")
                    public void startNode(String name, Class clazz) {
                        super.startNode(name, clazz);
                        cdata = needCDATA(targetClass, name);
                        if(!cdata && targetClass2 != null ){
                            cdata = needCDATA(targetClass2, name);
                        }
                    }

                    @Override
                    protected void writeText(QuickWriter writer, String text) {
                        if (cdata) {
                            writer.write("<![CDATA[");
                            writer.write(text);
                            writer.write("]]>");
                        } else {
                            writer.write(text);
                        }
                    }
                };
            }
        });
        return stream;
    }

    private static boolean needCDATA(Class<?> targetClass, String fieldAlias){
        boolean cdata = false;
        //first, scan self
        cdata = existsCDATA(targetClass, fieldAlias);
        if(cdata){
            return cdata;
        }
        //if cdata is false, scan supperClass until java.lang.Object
        Class<?> superClass = targetClass.getSuperclass();
        while(!superClass.equals(Object.class)){
            cdata = existsCDATA(superClass, fieldAlias);
            if(cdata) {
                return cdata;
            }
            superClass = superClass.getSuperclass();
        }
        return false;
    }

    private static boolean existsCDATA(Class<?> clazz, String fieldAlias){
        //scan fields
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //1. exists XStreamCDATA
            if(field.getAnnotation(XStreamCDATA.class) != null ){
                XStreamAlias xStreamAlias = field.getAnnotation(XStreamAlias.class);
                //2. exists XStreamAlias
                if(null != xStreamAlias){
                    if(fieldAlias.equals(xStreamAlias.value())){//matched
                        return true;
                    }
                }else{// not exists XStreamAlias
                    if(fieldAlias.equals(field.getName())){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public static XStream getXStream(Class<?> targetClass, Class<?>... subClasses) {
        XStream stream = new XStream(new XppDriver() {
            @Override
            public HierarchicalStreamWriter createWriter(Writer out) {
                return new PrettyPrintWriter(out, new XmlFriendlyReplacer("_-", "_")) {
                    // 对所有xml节点的转换都增加CDATA标记
                    boolean cdata = false;

                    @Override
                    @SuppressWarnings("rawtypes")
                    public void startNode(String name, Class clazz) {
                        super.startNode(name, clazz);
                        cdata = needCDATA(targetClass, name);
                        if (subClasses != null && !cdata) {
                            for (Class<?> subClass : subClasses) {
                                if (subClass != null) {
                                    cdata = needCDATA(subClass, name);
                                }
                            }
                        }
                    }

                    @Override
                    protected void writeText(QuickWriter writer, String text) {
                        if (cdata) {
                            writer.write("<![CDATA[");
                            writer.write(text);
                            writer.write("]]>");
                        } else {
                            writer.write(text);
                        }
                    }
                };
            }
        });
        return stream;
    }
}


ResponseSetUtils

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ResponseSetUtils {

    public static void set(HttpServletResponse response, HttpServletRequest request) {
        response.addHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.addHeader("Access-Control-Allow-Headers", "Accept,Authorization,DNT,Content-Type,Referer,User-Agent");
        response.addHeader("Access-Control-Allow-Credentials", "true");
    }

    /**
     * 设置下载头
     */
    public static void setResponseHeader(HttpServletResponse response, String fileName) {
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
        response.addHeader("Cache-control", "no-cache");
    }
}

controller

/**
     * 导出到xml
     *
     * @param response
     * @param request
     * @param param
     * @return
     */
    @PostMapping(value = "export-2-xml")
    public ResultModel<JSONObject> export2Xml(HttpServletResponse response, HttpServletRequest request,
                                              @RequestBody AdvertiseItemExportParam param) throws IOException {
        ResultModel<JSONObject> rst = new ResultModel<>();
        JSONObject track = new JSONObject().fluentPut("param", param);
        rst.setModule(track);
        try {
            // 登录校验;
            StringBuilder checkLoginMsg = new StringBuilder();
            BucSSOUser user = checkLoginUser(response, request, checkLoginMsg);
            if (StringUtils.isNotBlank(checkLoginMsg.toString())) {
                return ResultModel.failed(checkLoginMsg.toString());
            }

            // 用户信息;
            boolean agent = RealmIdEnum.AGENT_TENANT.getTenantId().equals(user.getRealmId());
            String no = agent ? user.getCorpUserId() : user.getEmpId();
            LoginUserRoleEnum loginUserRole = agent ? LoginUserRoleEnum.AGENT : LoginUserRoleEnum.INNER_USER;
            LoginUserModel userModel = new LoginUserModel(no, user.getNickNameCn(), agent, loginUserRole.name());

            // 分页查询数据;
            List allData = advertiseCommonController.getAllRows(param, userModel);

            // 转xml;
            XStream xStream;
            if (agent) {
                // 代理
                xStream = XStreamUtil.getXStream(OfferExportAgency.class);
                xStream.processAnnotations(OfferExportAgency.class);
            } else {
                // 非代理:运营、管理
                xStream = XStreamUtil.getXStream(OfferExportOperator.class);
                xStream.processAnnotations(OfferExportOperator.class);
            }
            xStream.alias("offerList", List.class);

            // 写输出流;
            String fileName = UUID.randomUUID().toString().replace("-", "") + ".xml";
            ResponseSetUtils.set(response, request);
            ResponseSetUtils.setResponseHeader(response, fileName);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(XML_VERSION_1_0_ENCODING_UTF_8.getBytes(StandardCharsets.UTF_8));
            xStream.toXML(allData, outputStream);
            outputStream.flush();
            outputStream.close();
            // 返回结果;
            rst.setSuccess(true);
            return rst;
        } catch (IOException e) {
            LOGGER.error("AdvertiseItemController.export2Xml process error,param:{}",
                    JSON.toJSONObject(param), e);
            rst.setErrorMsg("控制器异常:" + e.getMessage());
            return rst;
        }

    }

分页获取导出的数据

/**
     * 循环导出
     *
     * @param param 参数
     * @return
     */
    public List getAllRows(AdvertiseItemExportParam param, LoginUserModel userModel) {
        List allRows = new ArrayList<>();
        ResultModel<PageResult<BottomPoolOfferDTO>> queryList;

        int index = 1;
        do {

            param.setPageNum(index++);
            param.setPageSize(500);

            queryList = advertiseItemService.queryList(param, userModel);
            AssertUtil.isTrue(Objects.nonNull(queryList) && queryList.isSuccess(), "查询商品数据失败");
            AssertUtil.notNull(queryList.getModule(), "查询商品数据失败");
            List<BottomPoolOfferDTO> records = queryList.getModule().getResultList();
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(records)) {
                if (userModel.isAgentUser()) {
                    // 代理
                    allRows.addAll(records.stream()
                            .map(OfferExportAgency::fromBottomPoolOfferDTO)
                            .collect(Collectors.toList()));
                } else {
                    // 运营
                    allRows.addAll(records.stream()
                            .map(OfferExportOperator::fromBottomPoolOfferDTO)
                            .collect(Collectors.toList()));
                }
            }

        }
        // 如果当前已导出数据小于全量数据,同时后面还有可查询页时,继续循环查询;
        while ((allRows.size() < param.getExportSize()) && (index <= queryList.getModule().getPaginator()
                .getTotalPage()));

        return allRows;
    }

实体类

@Data
@XStreamAlias("offer")
public class OfferExportAgency {

    @HeaderName(value = "商品主图", width = 50)
    @XStreamCDATA
    private String mainUrl;
    @HeaderName(value = "商品id", width = 20)
    private Long itemId;
    @HeaderName(value = "商品名称", width = 30)
    @XStreamCDATA
    private String title;
    @HeaderName(value = "权益标签", width = 25)
    private String benefitLabels;
    @HeaderName("起批量")
    private Long startOrderNumber;
    @HeaderName("热度")
    private Long hotIndex;
    @HeaderName("吸引力")
    private Long attractionIndex;
    @HeaderName(value = "一级分类", width = 20)
    @XStreamCDATA
    private String cateLevel1Name;
    @HeaderName("二级分类")
    @XStreamCDATA
    private String cateLevel2Name;
    @HeaderName(value = "三级分类", width = 20)
    @XStreamCDATA
    private String cateLevel3Name;
    @HeaderName(value = "店铺名称", width = 30)
    @XStreamCDATA
    private String shopName;
    @HeaderName(value = "商品图url", width = 100)
    @XStreamCDATA
    private String imageUrls;

    public static OfferExportAgency fromBottomPoolOfferDTO(BottomPoolOfferDTO offerDTO) {
        OfferExportAgency offer = new OfferExportAgency();
        BeanUtils.copyProperties(offerDTO, offer);
        // 权益标签
        if (offerDTO.getBenefitLabels() != null) {
            offer.setBenefitLabels(
                    offerDTO.getBenefitLabels().parallelStream()
                            .map(AdvertiseItemPageQueryParam.BenefitLabelEnum::getDescByCode)
                            .collect(Collectors.toList()).toString()
            );
        }

        return offer;
    }

}

XStreamCDATA注解

package com.alibaba.china.tagnore.web.utils;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface XStreamCDATA {

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值