1.controller

package com.ccbft.seecloud.security.text.controller;

import com.ccbft.seecloud.common.core.util.R;
import com.ccbft.seecloud.security.text.config.ResourceConfig;
import com.ccbft.seecloud.security.text.entity.SecuritySensitiveWordEntity;
import com.ccbft.seecloud.security.text.entity.SecuritySensitiveWordStgEntity;
import com.ccbft.seecloud.security.text.service.WordStgService;
import com.ccbft.seecloud.security.text.vo.invo.AddWordInVo;
import com.ccbft.seecloud.security.text.vo.invo.DeleteWordInVo;
import com.ccbft.seecloud.security.text.vo.invo.EditWordInVo;
import com.ccbft.seecloud.security.text.vo.invo.GetWordListInVo;
import com.ccbft.seecloud.security.text.vo.outvo.AddWordOutVo;
import com.ccbft.seecloud.security.text.vo.outvo.DeleteWordOutVo;
import com.ccbft.seecloud.security.text.vo.outvo.EditWordOutVo;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;

@Slf4j
@RestController
@Api(value = "敏感词详情", tags = {"敏感词详情"})
@RequestMapping("/WordInfo")
public class WordInfoController {

    @Autowired
    private ResourceConfig resourceConfig;

    @Autowired
    com.ccbft.seecloud.security.text.service.WordInfoService WordInfoService;

    @Autowired
    private WordStgService wordStgService;

    @PostMapping(value = "/importSensitiveWord", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "敏感词导入 - fengwei", tags = {"fengwei"}, notes = "选中词库导入敏感词")
    public R<String> importSensitiveWord(@ApiParam(name = "file", value = "文件", required = true)
                                                 MultipartFile file,
                                         @ApiParam(name = "stgId", value = "获取敏感词仓库ID", required = true)
                                         @RequestParam String stgId) {
        if (null == file) {
            return R.failed("error:没有找到文件,导入失败");
        }
        if (!file.getOriginalFilename().endsWith(".xlsx")) {
            return R.failed("error:文件格式不正确!");
        }
        int size = Integer.parseInt(resourceConfig.getXlsxMaxSize());
        if (file.getSize() > size) {
            return R.failed("error:文件过大,导入失败");
        }
        SecuritySensitiveWordStgEntity wordByPk = wordStgService.getWordByPk(stgId);
        if (null == wordByPk) {
            return R.failed("error:该敏感词库不存在");
        }
        int affectCount = WordInfoService.importSensitiveWord(file, stgId);
        if (affectCount <= 0) {
            return R.failed("error:所获敏感词为空(可能包含重复数据)或含有超出150长度的敏感词");
        }
        return R.ok("success:词库" + stgId + ":成功导入" + affectCount + "条");
    }
}

 

2.service

package com.ccbft.seecloud.security.text.service;

import cn.hutool.core.lang.UUID;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.ccbft.seecloud.security.text.config.ResourceConfig;
import com.ccbft.seecloud.security.text.enmus.AppInfoEnum;
import com.ccbft.seecloud.security.text.entity.SecuritySensitiveWordEntity;
import com.ccbft.seecloud.security.text.listener.SensitiveWordData;
import com.ccbft.seecloud.security.text.listener.SensitiveWordListener;
import com.ccbft.seecloud.security.text.mapper.SecuritySensitiveWordMapper;
import com.ccbft.seecloud.security.text.mapper.SecuritySensitiveWordStgMapper;
import com.ccbft.seecloud.security.text.utils.ThreadPoolUtil;
import com.ccbft.seecloud.security.text.vo.invo.AddWordInVo;
import com.ccbft.seecloud.security.text.vo.invo.DeleteWordInVo;
import com.ccbft.seecloud.security.text.vo.invo.EditWordInVo;
import com.ccbft.seecloud.security.text.vo.invo.GetWordListInVo;
import com.ccbft.seecloud.security.text.vo.outvo.AddWordOutVo;
import com.ccbft.seecloud.security.text.vo.outvo.DeleteWordOutVo;
import com.ccbft.seecloud.security.text.vo.outvo.EditWordOutVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class WordInfoService {

    @Resource
    SecuritySensitiveWordMapper securitySensitiveWordMapper;
    @Autowired
    CommonService commonService;

    @Resource
    private SecuritySensitiveWordStgMapper wordStgMapper;

    @Autowired
    private ResourceConfig resourceConfig;

    private static Integer affectCount = 0;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    public int importSensitiveWord(MultipartFile file, String stgId) {
        affectCount = 0;
        FileOutputStream fileOutputStream = null;
        InputStream inputStream = null;
        ExcelReader excelReader = null;
        try {
            // 1.获取文件流
            String temDirPath = String.format("%s/%s", resourceConfig.getXlxsPath(), "upload_temp");

            String tempDir = temDirPath + File.separator + file.getOriginalFilename();
            File outFile = new File(tempDir);
            // 2.判断文件夹是否存在,不存在则创建
            if (null != outFile.getParentFile()) {
                outFile.getParentFile().mkdirs();
            }
            // 3.创建输出流,文件输出保存到目录
            fileOutputStream = new FileOutputStream(outFile);
            inputStream = file.getInputStream();
            IOUtils.copy(inputStream, fileOutputStream);

            // 4.读取xlxs,并创建监听器读取其中的sheet
            SensitiveWordListener sensitiveWordListener = new SensitiveWordListener(stgId, this,
                    dataSourceTransactionManager, transactionDefinition);
            excelReader = EasyExcel.read(outFile, SensitiveWordData.class, sensitiveWordListener).build();
            ReadSheet readSheet = EasyExcel.readSheet(0).build(); //忽略第一行
            excelReader.read(readSheet);

            return affectCount;
        } catch (IOException e) {
            log.error("WordInfoService importSensitiveWord:文件解析失败",e);
            return 0;
        } finally {
            if (null != fileOutputStream) {
                try {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (Exception ex) {
                    log.error("WordInfoService importSensitiveWord:文件关闭失败",ex);
                    ex.printStackTrace();
                }
            }
            if (null != excelReader) {
                excelReader.finish();
            }
        }
    }

    public void batchInsert(String stgId, List<SensitiveWordData> list,
                            DataSourceTransactionManager dataSourceTransactionManager,
                            TransactionStatus transactionStatus) {
        if (Collections.isEmpty(list)) {
            return;
        }
        Timestamp t = new Timestamp(new Date().getTime());
        List<SecuritySensitiveWordEntity> entityList = new ArrayList<>();

        List<String> wordList = securitySensitiveWordMapper.selectAllWordByStgId(stgId);
        for (SensitiveWordData data : list) {
            String sensitiveWord = data.getSensitiveWord();
            if (StringUtils.isEmpty(sensitiveWord) || wordList.contains(sensitiveWord)) {
                continue;
            }
            // 敏感词和描述长度都不能超过50
            if (sensitiveWord.length() > 150) {
                dataSourceTransactionManager.rollback(transactionStatus);
                log.error("WordInfoService batchInsert:导入失败:敏感词长度不能超过150");
                affectCount = -1;
                return;
            }
            String describe = data.getDescribe();
            if (StringUtils.isNoneBlank(describe) && describe.length() > 150) {
                dataSourceTransactionManager.rollback(transactionStatus);
                log.error("WordInfoService batchInsert:导入失败:敏感词描述长度不能超过150");
                affectCount = -2;
                return;
            }
            SecuritySensitiveWordEntity entity = new SecuritySensitiveWordEntity();
            entity.setWord(sensitiveWord);
            entity.setDescribe(describe);
            entity.setId(UUID.randomUUID().toString().trim());
            entity.setWordStgId(stgId);
            entity.setCreateTime(t);

            entityList.add(entity);
        }
        if (Collections.isEmpty(entityList)) {
            return;
        }
        affectCount += securitySensitiveWordMapper.insertForeach(entityList);
    }

}

 

3.excel列所映射的实体

package com.ccbft.seecloud.security.text.listener;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class SensitiveWordData {
    @ExcelProperty(index = 0)
    private String sensitiveWord;

    @ExcelProperty(index = 1)
    private String describe;
}

 

4.excel解析监听

package com.ccbft.seecloud.security.text.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ccbft.seecloud.security.text.service.WordInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class SensitiveWordListener extends AnalysisEventListener<SensitiveWordData> {

    private static final int BATCH_COUNT = 500;
    private List<SensitiveWordData> list = new ArrayList<>();

    //事务管理
    private DataSourceTransactionManager dataSourceTransactionManager;
    private DefaultTransactionDefinition transactionDefinition;
    private TransactionStatus transactionStatus = null;

    private WordInfoService service;
    private String stgId;

    public SensitiveWordListener(String stgId,WordInfoService service,
                                 DataSourceTransactionManager dataSourceTransactionManager,
                                 TransactionDefinition transactionDefinition) {
        this.stgId = stgId;
        this.service = service;

        this.dataSourceTransactionManager = dataSourceTransactionManager;
        this.transactionDefinition = new DefaultTransactionDefinition(transactionDefinition);
        //设置事务的隔离级别 :未提交读写
        this.transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        // 手动开启事务
        this.transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
    }

    @Override
    public void invoke(SensitiveWordData sensitiveWord, AnalysisContext analysisContext) {
        boolean hasCompleted = transactionStatus.isCompleted();
        // 如果事务已经关闭
        if (hasCompleted){
            return;
        }
        // 1.将解析好的数据存储到list中
        list.add(sensitiveWord);
        // 2.判断list大小是否达到BATCH_COUNT,如果达到则存储到数据库中
        if (list.size() >= BATCH_COUNT) {
            service.batchInsert(stgId ,list, dataSourceTransactionManager, transactionStatus);
            log.info("SensitiveWordListener service.batchInsert:success");
            list.clear();
        }

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        boolean hasCompleted = transactionStatus.isCompleted();
        if (hasCompleted){
            return;
        }
        service.batchInsert(stgId ,list, dataSourceTransactionManager, transactionStatus);
        log.info("SensitiveWordListener service.batchInsert:success");
        hasCompleted = transactionStatus.isCompleted();
        if (!hasCompleted){
            //提交事务
            dataSourceTransactionManager.commit(transactionStatus);
            log.info("SensitiveWordListener doAfterAllAnalysed:当前事务已提交");

        }
    }

}

 

最后修改于 2020-12-30 01:27:52
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付
上一篇