實戰(zhàn):第十二章:txt文件轉(zhuǎn)xml文件

開發(fā)不就這么點事嗎,有個啥好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;
     
        /**
         * 數(shù)據(jù)發(fā)布接口需要執(zhí)行:
         * 1.判斷發(fā)布范圍(releaseScope=‘serviceCode,serviceCode,serviceCode’)不能超過訂閱范圍String[]
         * 2.將文件校驗(是否為空,是否超過300M)并轉(zhuǎn)為XML文件存儲(盤符:/App/Service/Date/xx.xml)
         *   xml格式:<list><service>serviceCode</service><range>releaseScope</range><data><![CDATA[文本內(nèi)容]]></![CDATA[文本內(nèi)容]]></data></list>
         * 3.發(fā)送MQ:將訂閱信息,發(fā)布范圍,文件存儲路徑,token發(fā)送
         * 4.添加數(shù)據(jù)發(fā)布記錄
         * 5.添加數(shù)據(jù)發(fā)布日志記錄
         * @param dataDistributionVo
         * @return
         */
        @Transactional
        @Override
        public JSONObject dataDistribution(DataDistributionVo dataDistributionVo) {
            //錯誤信息收集
            String errorLog = "";
            StringBuffer stringBuffer = new StringBuffer(errorLog);
     
            //發(fā)布范圍不能超過訂閱范圍  獲取訂閱信息
            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 {
                //獲取訂閱范圍: 將所有服務(wù)標(biāo)識獲取出來存入字符數(shù)組,這個數(shù)組就是訂閱范圍
                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())){
                    //遍歷發(fā)布范圍 OA,ERP,RS
                    String[] split = dataDistributionVo.getReleaseScope().split(",");
                    for (String dataDistributionServiceCode : split) {
                        //判斷該發(fā)布范圍是否包含在訂閱范圍內(nèi)
                        boolean contains = Arrays.asList(strings).contains(dataDistributionServiceCode);
                        if(!contains){
                            //發(fā)布不包含在訂閱范圍內(nèi)
                            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是對應(yīng)300M的字節(jié)
                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()){
                            //不存在時,創(chuàng)建文件夾
                            saveFile.mkdirs();
                        }
                        //將txt文本文件轉(zhuǎn)成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();
                    }
                }
            }
     
     
            //發(fā)送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);
     
            //添加數(shù)據(jù)發(fā)布記錄
            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(";");
            }
     
            //添加數(shù)據(jù)發(fā)布日志記錄
            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(";");
            }
     
            //返回結(jié)果
            JSONObject jsonObject = new JSONObject();
            if(StringUtil.isEmpty(errorLog)){
                jsonObject.put("success","執(zhí)行成功");
            }else {
                jsonObject.put("faile",stringBuffer.toString());
            }
            return jsonObject;
        }
     
        /**
         * txt類型轉(zhuǎn)xml
         * @param dataDistributionVo
         * @param fileUrl
         * @param errorLog
         * @param stringBuffer
         */
        private void txtToXml(DataDistributionVo dataDistributionVo,String fileUrl,String errorLog,StringBuffer stringBuffer){
            //multipartFile類型轉(zhuǎn)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編碼,而不用環(huán)境編碼格式,因為環(huán)境默認(rèn)編碼不等于操作系統(tǒng)編碼
                        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 + "]]>";
                    //文本轉(zhuǎn)xml
                    Document document = DocumentHelper.createDocument();
                    //需要一個根節(jié)點list,否則重新寫入是會出現(xiàn)無法向此文檔添加已存在的元素
                    Element list = document.addElement("list");
                    Element service = list.addElement("service");
                    Element range = list.addElement("range");
                    Element data = list.addElement("data");//<![CDATA[文本內(nèi)容]]>
                    //設(shè)置節(jié)點數(shù)據(jù)
                    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轉(zhuǎn)File過程中發(fā)生異常,導(dǎo)致傳出來是一個空的file
                errorLog = DatabusConstant.ERROR_LOG_MULTIPARTFILE_TO_FILE;
                stringBuffer.append(errorLog).append(";");
            }
        }
     
        /**
         * multipartFile轉(zhuǎn)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);
                //讀取的內(nèi)容的長度,用來裝數(shù)據(jù)
                int bytesRead = 0;
                //緩沖區(qū)數(shù)組
                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;
                        }
                        //單獨出現(xiàn)BF以下的,也算是GBK
                        if (0x80 <= read && read <= 0xBF) {
                            break;
                        }
                        if (0xC0 <= read && read <= 0xDF) {
                            read = bis.read();
                            if (0x80 <= read && read <= 0xBF) {
                                //雙字節(jié) (0xC0 - 0xDF) (0x80 - 0xBF),也可能在GB編碼內(nèi)
                                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;//數(shù)據(jù)包
        String releaseScope;//發(fā)布范圍 例如:OA,ERP,RS
        String appId;//應(yīng)用id
        String appCode;//應(yīng)用標(biāo)識
        String serviceName;//服務(wù)名稱
        String serviceCode;//服務(wù)標(biāo)識
        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;
        }
    }