实战:第十二章:txt文件转xml文件

本文涉及的产品
数据可视化DataV,5个大屏 1个月
可视分析地图(DataV-Atlas),3 个项目,100M 存储空间
简介: 实战:第十二章:txt文件转xml文件

开发不就这么点事吗,有个啥好bb的

controller

 

@RequestMapping("/DataDistributionController")
@RestController
public class DataDistributionController {
    @Autowired
    DataDistributionService dataDistributionService;
    @PostMapping("/dataDistribution")
    public JSONObject dataDistribution(DataDistributionVo dataDistributionVo){
        return dataDistributionService.dataDistribution(dataDistributionVo);
    }
}

serviceimpl

import cn.dreamit.dreamweb.util.UUIDGenerator;
import cn.dreamit.one.databus.constant.DatabusConstant;
import cn.dreamit.one.databus.service.DataDistributionService;
import cn.dreamit.one.databus.service.SubscriptionInfoService;
import cn.dreamit.one.databus.vo.DataDistributionVo;
import cn.dreamit.one.databus.vo.SendMqDataVo;
import cn.dreamit.one.entity.SubscriptionEntity;
import cn.dreamit.one.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import xsf.data.DBManager;
import xsf.data.DbType;
import xsf.data.Parameter;
import xsf.data.Sql;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@Service
public class DataDistributionServiceImpl implements DataDistributionService {
    @Autowired
    SubscriptionInfoService subscriptionInfoService;
    @Autowired
    private AmqpTemplate rabbitTemplate;
    /**
     * 数据发布接口需要执行:
     * 1.判断发布范围(releaseScope=‘serviceCode,serviceCode,serviceCode’)不能超过订阅范围String[]
     * 2.将文件校验(是否为空,是否超过300M)并转为XML文件存储(盘符:/App/Service/Date/xx.xml)
     *   xml格式:<list><service>serviceCode</service><range>releaseScope</range><data><![CDATA[文本内容]]></![CDATA[文本内容]]></data></list>
     * 3.发送MQ:将订阅信息,发布范围,文件存储路径,token发送
     * 4.添加数据发布记录
     * 5.添加数据发布日志记录
     * @param dataDistributionVo
     * @return
     */
    @Transactional
    @Override
    public JSONObject dataDistribution(DataDistributionVo dataDistributionVo) {
        //错误信息收集
        String errorLog = "";
        StringBuffer stringBuffer = new StringBuffer(errorLog);
        //发布范围不能超过订阅范围  获取订阅信息
        JSONObject subscriptionInfo = subscriptionInfoService.getSubscriptionInfo(dataDistributionVo.getAppId(), dataDistributionVo.getAppCode(),
                dataDistributionVo.getServiceName(), dataDistributionVo.getServiceCode(), null, null, null);
        List<SubscriptionEntity> subscriptionList = (List<SubscriptionEntity>) subscriptionInfo.get("subscriptionList");
        if(CollectionUtils.isEmpty(subscriptionList)){
            errorLog = DatabusConstant.ERROR_LOG_SUBSCRIPTION;
            stringBuffer.append(errorLog).append(";");
        }else {
            //获取订阅范围: 将所有服务标识获取出来存入字符数组,这个数组就是订阅范围
            String[] strings = new String[subscriptionList.size()];
            for (int i = 0; i < subscriptionList.size(); i++) {
                strings[i] = subscriptionList.get(i).getSERVICE_CODE();
            }
            if(!StringUtil.isEmpty(dataDistributionVo.getReleaseScope())){
                //遍历发布范围 OA,ERP,RS
                String[] split = dataDistributionVo.getReleaseScope().split(",");
                for (String dataDistributionServiceCode : split) {
                    //判断该发布范围是否包含在订阅范围内
                    boolean contains = Arrays.asList(strings).contains(dataDistributionServiceCode);
                    if(!contains){
                        //发布不包含在订阅范围内
                        errorLog = DatabusConstant.ERROR_LOG_RELEASESCOPE;
                        stringBuffer.append(errorLog).append(";");
                    }
                }
            }
        }
        String fileUrl = "";
        //文件和文件名不能为空
        if(dataDistributionVo.getFile().isEmpty() || "".equals(dataDistributionVo.getFile().getOriginalFilename())){
            errorLog = DatabusConstant.ERROR_LOG_FILE_NOT_EMPTY;
            stringBuffer.append(errorLog).append(";");
        }else {
            //文件大小不能超过300M,314572800是对应300M的字节
            if(dataDistributionVo.getFile().getSize() > 314572800){
                errorLog = DatabusConstant.ERROR_LOG_FILE_SIZE;
                stringBuffer.append(errorLog).append(";");
            }else {
                String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                //拼接路径 盘符:D:/  +  App/Service/Date/
                fileUrl = DatabusConstant.DISK_CHARACTER +  dataDistributionVo.getAppCode() + "/" + dataDistributionVo.getServiceCode() + "/" + format + "/";
                try {
                    File saveFile = new File(fileUrl);
                    if(!saveFile.exists()){
                        //不存在时,创建文件夹
                        saveFile.mkdirs();
                    }
                    //将txt文本文件转成xml文件写入磁盘
                    txtToXml(dataDistributionVo,fileUrl,errorLog,stringBuffer);
//                    //直接保存的txt文件
//                    File data = new File(saveFile, dataDistributionVo.getFile().getName());
//                    //保存文件,使用transferTo()保存必须要绝对路径且文件夹必须已存在,否则报错
//                    dataDistributionVo.getFile().transferTo(data);
                } catch (Exception e) {
                    errorLog = DatabusConstant.ERROT_LOG_FILE_UPLOAD + e.getMessage();
                    stringBuffer.append(errorLog).append(";");
                    System.out.println(e.getMessage());
                    e.printStackTrace();
                }
            }
        }
        //发送MQ
        String sendKey = "serviceCode:" + dataDistributionVo.getServiceCode();
        SendMqDataVo sendMqDataVo = new SendMqDataVo();
        sendMqDataVo.setFileUrl(fileUrl + dataDistributionVo.getFile().getName());
        sendMqDataVo.setReleaseRange(dataDistributionVo.getReleaseScope());
        sendMqDataVo.setSubscriptionEntityList(subscriptionList);
        sendMqDataVo.setToken(dataDistributionVo.getPubToken());
        rabbitTemplate.convertAndSend(sendKey,sendMqDataVo);
        //添加数据发布记录
        String uuid = UUIDGenerator.getUUID();
        Sql dataServiceSql = new Sql("INSERT INTO `g_app_data_service`(ID,APP_ID,APP_CODE,SERVICE_NAME,SERVICE_CODE,MEMO) VALUES(?,?,?,?,?,?)");
        dataServiceSql.addParameter(new Parameter("ID", uuid , DbType.STRING));
        dataServiceSql.addParameter(new Parameter("APP_ID", dataDistributionVo.getAppId(), DbType.STRING));
        dataServiceSql.addParameter(new Parameter("APP_CODE", dataDistributionVo.getAppCode(), DbType.STRING));
        dataServiceSql.addParameter(new Parameter("SERVICE_NAME", dataDistributionVo.getServiceName(), DbType.STRING));
        dataServiceSql.addParameter(new Parameter("SERVICE_CODE", dataDistributionVo.getServiceCode(), DbType.STRING));
        dataServiceSql.addParameter(new Parameter("MEMO", dataDistributionVo.getMemo(), DbType.STRING));
        String flag = DBManager.execute(dataServiceSql) ? uuid : null;
        if(StringUtil.isEmpty(flag)){
            errorLog = DatabusConstant.ERROR_LOG_INSERT_DATADISTRIBUTION;
            stringBuffer.append(errorLog).append(";");
        }
        //添加数据发布日志记录
        Sql sqlDataServiceLog = new Sql("INSERT INTO `g_app_data_service_log`(ID,PUBAPP_CODE,PUBAPP_NAME,SERVICE_ID,SERVICE_NAME,PUB_RANGE,PUB_TOKEN,MQ_CHANNEL,PUB_TIME,ERROE_LOG) VALUES(?,?,?,?,?,?,?,?,?,?)");
        sqlDataServiceLog.addParameter(new Parameter("ID", uuid , DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("PUBAPP_CODE", dataDistributionVo.getAppId() , DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("PUBAPP_NAME",  null, DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("SERVICE_ID",  null , DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("SERVICE_NAME", dataDistributionVo.getServiceName() , DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("PUB_RANGE", dataDistributionVo.getServiceCode() , DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("PUB_TOKEN", dataDistributionVo.getPubToken()  , DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("MQ_CHANNEL", sendKey , DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("PUB_TIME", new Date(), DbType.STRING));
        sqlDataServiceLog.addParameter(new Parameter("ERROE_LOG", stringBuffer.toString(), DbType.STRING));
        String bool = DBManager.execute(dataServiceSql) ? uuid : null;
        if(StringUtil.isEmpty(bool)){
            errorLog = DatabusConstant.ERROR_LOG_INSERT_DATADISTRIBUTION_Log;
            stringBuffer.append(errorLog).append(";");
        }
        //返回结果
        JSONObject jsonObject = new JSONObject();
        if(StringUtil.isEmpty(errorLog)){
            jsonObject.put("success","执行成功");
        }else {
            jsonObject.put("faile",stringBuffer.toString());
        }
        return jsonObject;
    }
    /**
     * txt类型转xml
     * @param dataDistributionVo
     * @param fileUrl
     * @param errorLog
     * @param stringBuffer
     */
    private void txtToXml(DataDistributionVo dataDistributionVo,String fileUrl,String errorLog,StringBuffer stringBuffer){
        //multipartFile类型转File类型
        File multipartFileToFile = multipartFileToFile(dataDistributionVo.getFile(),fileUrl,errorLog,stringBuffer);
        if(multipartFileToFile != null){
            StringBuffer buffer = new StringBuffer();
            try {
                //解决中文乱码
                String code = getFileEncode(multipartFileToFile.getAbsolutePath(),errorLog,stringBuffer);
                if("asci".equals(code)){
                    // 这里采用GBK编码,而不用环境编码格式,因为环境默认编码不等于操作系统编码
                    code = "GBK";
                }
                BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(multipartFileToFile), code));
                String line = null;
                while((line = br.readLine()) != null){
                    buffer.append(line.trim());
                }
                String dataText = buffer.toString();
                String txtToXml = "<![CDATA[" + dataText + "]]>";
                //文本转xml
                Document document = DocumentHelper.createDocument();
                //需要一个根节点list,否则重新写入是会出现无法向此文档添加已存在的元素
                Element list = document.addElement("list");
                Element service = list.addElement("service");
                Element range = list.addElement("range");
                Element data = list.addElement("data");//<![CDATA[文本内容]]>
                //设置节点数据
                data.setText(txtToXml);
                service.setText(dataDistributionVo.getServiceCode());
                range.setText(dataDistributionVo.getReleaseScope());
                //写入xml文件
                String xmlUrl = fileUrl + dataDistributionVo.getFile().getOriginalFilename() + ".xml";
                //如果存在则重新写入
                Writer filewriter = new FileWriter(xmlUrl);
                XMLWriter xmlWriter = new XMLWriter(filewriter);
                xmlWriter.write(document);
                xmlWriter.close();
            } catch (IOException e) {
                errorLog = DatabusConstant.ERROR_LOG_TXT_TO_XML;
                stringBuffer.append(errorLog).append(";");
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }else {
            //如果file为空,则在multipartFile转File过程中发生异常,导致传出来是一个空的file
            errorLog = DatabusConstant.ERROR_LOG_MULTIPARTFILE_TO_FILE;
            stringBuffer.append(errorLog).append(";");
        }
    }
    /**
     * multipartFile转File
     * @param file
     * @param errorLog
     * @param stringBuffer
     * @return
     */
    private File multipartFileToFile(MultipartFile file,String fileUrl,String errorLog,StringBuffer stringBuffer){
        File toFile = null;
        try {
            InputStream ins = file.getInputStream();
            toFile = new File(fileUrl,file.getOriginalFilename());
            OutputStream os = new FileOutputStream(toFile);
            //读取的内容的长度,用来装数据
            int bytesRead = 0;
            //缓冲区数组
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer,0,8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (IOException e) {
            errorLog = DatabusConstant.ERROR_LOG_MULTIPARTFILE_TO_FILE;
            stringBuffer.append(errorLog).append(";");
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return toFile;
    }
    /**
     * 获取文件编码
     * @param path 文件的路径
     * @return
     */
    private String getFileEncode(String path,String errorLog,StringBuffer stringBuffer) {
        String charset ="asci";
        byte[] first3Bytes = new byte[3];
        BufferedInputStream bis = null;
        try {
            boolean checked = false;
            bis = new BufferedInputStream(new FileInputStream(path));
            bis.mark(0);
            int read = bis.read(first3Bytes, 0, 3);
            if (read == -1)
                return charset;
            if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
                charset = "Unicode";//UTF-16LE
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) {
                charset = "Unicode";//UTF-16BE
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB && first3Bytes[2] == (byte) 0xBF) {
                charset = "UTF8";
                checked = true;
            }
            bis.reset();
            if (!checked) {
                int loc = 0;
                while ((read = bis.read()) != -1) {
                    loc++;
                    if (read >= 0xF0) {
                        break;
                    }
                    //单独出现BF以下的,也算是GBK
                    if (0x80 <= read && read <= 0xBF) {
                        break;
                    }
                    if (0xC0 <= read && read <= 0xDF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) {
                            //双字节 (0xC0 - 0xDF) (0x80 - 0xBF),也可能在GB编码内
                            continue;
                        }else{
                            break;
                        }
                    } else if (0xE0 <= read && read <= 0xEF) { //也有可能出错,但是几率较小
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) {
                            read = bis.read();
                            if (0x80 <= read && read <= 0xBF) {
                                charset = "UTF-8";
                                break;
                            } else{
                                break;
                            }
                        } else{
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            errorLog = DatabusConstant.ERROR_LOG_FILE_ENCODE;
            stringBuffer.append(errorLog).append(";");
            System.out.println(e.getMessage());
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException ex) {
                    errorLog = DatabusConstant.ERROR_LOG_FILE_ENCODE;
                    stringBuffer.append(errorLog).append(";");
                    System.out.println(ex.getMessage());
                }
            }
        }
        return charset;
    }
}
import org.springframework.web.multipart.MultipartFile;
public class DataDistributionVo {
    MultipartFile file;//数据包
    String releaseScope;//发布范围 例如:OA,ERP,RS
    String appId;//应用id
    String appCode;//应用标识
    String serviceName;//服务名称
    String serviceCode;//服务标识
    String memo;//备注
    String pubToken;//token
    public MultipartFile getFile() {
        return file;
    }
    public void setFile(MultipartFile file) {
        this.file = file;
    }
    public String getReleaseScope() {
        return releaseScope;
    }
    public void setReleaseScope(String releaseScope) {
        this.releaseScope = releaseScope;
    }
    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }
    public String getAppCode() {
        return appCode;
    }
    public void setAppCode(String appCode) {
        this.appCode = appCode;
    }
    public String getServiceName() {
        return serviceName;
    }
    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }
    public String getServiceCode() {
        return serviceCode;
    }
    public void setServiceCode(String serviceCode) {
        this.serviceCode = serviceCode;
    }
    public String getMemo() {
        return memo;
    }
    public void setMemo(String memo) {
        this.memo = memo;
    }
    public String getPubToken() {
        return pubToken;
    }
    public void setPubToken(String pubToken) {
        this.pubToken = pubToken;
    }
}
相关实践学习
DataV Board用户界面概览
本实验带领用户熟悉DataV Board这款可视化产品的用户界面
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
相关文章
|
1月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
60 1
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
16天前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
72 8
|
1月前
|
XML JavaScript Java
java与XML文件的读写
java与XML文件的读写
26 3
|
1月前
|
XML 存储 缓存
C#使用XML文件的详解及示例
C#使用XML文件的详解及示例
96 0
|
1月前
|
XML 存储 Web App开发
查看 XML 文件
查看 XML 文件
|
3月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
2月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
48 1
|
3月前
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
5月前
|
XML Java 数据格式
java创建xml文件内容
java创建xml文件内容