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 {

}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/761138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

clion远程开发

clion远程开发 简要概括&#xff1a; 建立 SFTP 通讯&#xff0c;创建远程目录与本地目录的映射文件夹&#xff0c;就可以把本机文件夹中的文件用鼠标右键选中上全传&#xff0c;打开自动同步功能&#xff0c;后面更改文件就可以自动同步文件了。 一.新建SFTP远程链接服务 …

C++感受12-Hello Object 派生版

不变的功能&#xff0c;希望直接复用原有代码&#xff1b;变化的功能&#xff0c;希望在分开的代码里实现。 派生的基本概念和目的如何定义派生类以及创建派生对象派生对象的生死过程 0. 课堂视频 ff14-HelloObject-派生版 1. 派生的基本概念与目的 编程&#xff0c;或者说软…

无线领夹麦克风可以唱歌吗?推荐多款收音好的无线麦克风

如今是一个短视频营销飞速发展的时代&#xff0c;越来越多自媒体人通过短视频的方式来进行直播带货、生活Vlog、线上K歌等&#xff0c;记录下生活里那美丽的瞬间。不过也有不少新手视频创作者存在疑问&#xff1a;无线领夹麦克风可以唱歌吗&#xff1f; 答案是可以的&#xff0…

前端技术(二)——javasctipt 介绍

一、javascript基础 1. javascript简介 ⑴ javascript的起源 ⑵ javascript 简史 ⑶ javascript发展的时间线 ⑷ javascript的实现 ⑸ js第一个代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>…

SSM“点点通”餐饮点餐小程序-计算机毕业设计源码11264

摘要 随着中国经济的飞速增长&#xff0c;消费者的智能化水平不断提高&#xff0c;许多智能手机和相关的软件正在得到更多的关注和支持。其中&#xff0c;微信的餐饮点餐小程序更是深得消费者的喜爱&#xff0c;它的出现极大地改善了消费者的生活质量&#xff0c;同时&#xf…

电商价格监测:品牌控价维权的关键利器

品牌在进行控价时&#xff0c;所面对的是线上成千上万条的商品链接&#xff0c;如果仅依靠人工&#xff0c;根本无法做到准确且全面地完成电商价格监测工作。因此&#xff0c;一套准确率高的电商价格监测系统对于品牌的控价维权而言&#xff0c;其重要性不言而喻。 在形形色色的…

昇思25天学习打卡营第八天|保存与加载

背景 提供免费算力支持&#xff0c;有交流群有值班教师答疑的华为昇思训练营进入第八天了。 今天是第八天&#xff0c;前七天的学习内容可以看链接 昇思25天学习打卡营第一天|快速入门 昇思25天学习打卡营第二天|张量 Tensor 昇思25天学习打卡营第三天|数据集Dataset 昇思25天…

GPT-5:下一代AI如何彻底改变我们的未来

GPT-5 发布前瞻&#xff1a;技术突破与未来展望 随着科技的飞速发展&#xff0c;人工智能领域不断迎来新的突破。根据最新消息&#xff0c;OpenAI 的首席技术官米拉穆拉蒂在一次采访中确认&#xff0c;GPT-5 将在一年半后发布&#xff0c;并描述了其从 GPT-4 到 GPT-5 的飞跃如…

分布式限流:Spring Cloud Gateway 限流

分布式限流&#xff1a;Spring Cloud Gateway 限流 在现代微服务架构中&#xff0c;流量控制是一个至关重要的部分。分布式限流作为一种有效的流量控制手段&#xff0c;能够帮助我们保护系统不被突发的流量冲垮。Spring Cloud Gateway支持多种限流方式。 什么是分布式限流 分…

嵌入式UI开发-lvgl+wsl2+vscode系列:8、控件(Widgets)(一)

一、前言 这里将介绍一系列控件&#xff0c;了解后就可以开始基础的开发了。 二、示例 1、Base Obj&#xff08;基础对象&#xff09; 1.1、示例1 #include "../../lv_examples.h" #if LV_BUILD_EXAMPLESvoid lv_example_obj_1(void) {lv_obj_t * obj1;obj1 lv…

商城积分系统的代码实现(下)-- 积分订单的退款与结算

一、接着上文 用户在消耗积分的时候&#xff0c;需要根据一定的逻辑&#xff0c;除了扣减账户的当前余额&#xff0c;还需要依次消费积分订单的余额。 private void updatePointsOrderByUse(Integer schoolId, Long userId, String pointsType, int usingPoints) {List<Po…

springboot+vue 开发记录(八) 前端项目打包

本篇文章涉及到前端项目打包的一些说明 我打包后的项目在部署到服务器上后&#xff0c;访问页面时按下F12出现了这种情况&#xff1a; 它显示出了我的源码&#xff0c;这是一种很不安全的行为 该怎么办&#xff1f;很简单&#xff1a; 我们只需要下载一点点插件&#xff0c;再…

怎样查看vsphere client 的登录日志

- 问题摘要&#xff1a; 怎样查看vsphere client 的登录日志 - 解决方案/工作方法 1.登录vsphere client > vc > Monitor > Tasks and Events > Events, 查看日志 2. 查看VC 的websso.log日志 /var/log/vmware/sso/websso.log 3. 可以把websso.log文件拿到本地电…

苏东坡传-读书笔记六

苏东坡今生的浩然之气用尽。人的生活也就是心灵的生活&#xff0c;这种力量形成人的事业人品&#xff0c;与生命俱来&#xff0c;由生活中之遭遇而显示其形态。正如苏东坡在潮州韩文公庙碑中所说&#xff1a;“浩然之气、不依形而立&#xff0c;不恃力而行&#xff0c;不待生而…

智能驾驶系列报告:特斯拉智能驾驶方案简剖

不同于绝大多数国内车企在自动驾驶上采取多传感器融合方案&#xff0c;特斯拉FSD在发展初期就摒弃激光雷达、且不配备高清地图&#xff0c;成为在感知层以摄像头为核心的纯视觉解决方案代表;其依靠车身搭载的摄像头来捕捉周围的环境信息&#xff0c;并经过算法及神经网络模型处…

手机ip地址是实时位置吗

在数字时代&#xff0c;手机IP地址对于许多用户而言&#xff0c;似乎是一个既神秘又重要的存在。不少人都曾听说过&#xff0c;通过追踪IP地址可以定位到某个人的大致位置。那么&#xff0c;手机IP地址真的是实时位置的精确反映吗&#xff1f;本文将带您深入了解手机IP地址的真…

「网站开发必备」8款免费 React Gallery, Lightbox, 和 Photo Viewer开发库

大家好&#xff0c;今天给大家分8款免费 React Gallery, Lightbox, 和 Photo Viewer开发库。 在不断发展的网络开发世界中&#xff0c;开源库提供了大量创新和效率的机会。本文将带您了解一些用于Gallery, Lightbox, 和 Photo Viewer的最好的开源 React 库&#xff0c;为您的下…

2.00004 优化器执行计划生成的流程是怎么样的?

文章目录 整体架构关键结构体PlannerInfo (pathnodes.h:195)PlannerGlobal (pathnodes.h:95)函数栈关键函数pg_plan_query (postgres.c:885)planner (planner.c:274)standard_planner (planner.c:287)subquery_planner (planner.c:628)整体架构 关键结构体 PlannerInfo (pathn…

基于CST2024 Python内部环境的双锥天线自动3D建模和仿真

CST Studio Suite 2024版里面的Python相较于之前有了大的变化。 第一&#xff0c; 增加了cst.asymptotic &#xff0c;cst.radar &#xff0c;cst.units 三个包。 第二&#xff0c;之前CST python只能通过外部环境去操作&#xff0c;现在增加了内部环境控制&#xff0c;可以内…

Zabbix对接Elasticsearch(ES)数据库(未成功)

0.需求分析 不管zabbix的后端数据库是oracle还是mysql&#xff0c;当zabbix监控的量级达到了一定程度后&#xff0c;那么对数据库的性能是一个非常严峻的挑战。特别是对历史数据的查询&#xff0c;将会变得非常非常的慢&#xff0c;别告诉我可以建索引优化&#xff0c;当量级达…