实战:第十二章: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;
}
}