文件存放数据库

需求:工作遇到需要把.cer格式或.sm2格式的证书文件存放到数据库,用的时侯进行读取。

一、存储

1.上传证书到后台

在控制器获取到文件流先缓存一个临时文件到服务器,并返回临时文件的绝对路径

    public ActionResult<String> uploadMerchantCert(@RequestParam("file") MultipartFile file, @RequestParam("fileType") Integer fileType) {
        if (file.isEmpty()){
            throw new ApplicationException(ErrorCodes.INVALID_ARGUMENTS,"请选择上传文件");
        }
        String fileName = file.getOriginalFilename();
        if (fileType.equals(1) && !fileName.toLowerCase().endsWith(".cer")) {
            throw new ApplicationException(ErrorCodes.INVALID_UPLOAD_FILE_TYPE, "文件类型错误");
        } else if (fileType.equals(2) && !fileName.toLowerCase().endsWith(".sm2")) {
            throw new ApplicationException(ErrorCodes.INVALID_UPLOAD_FILE_TYPE, "文件类型错误");
        }

        File tempFile = null;
        String typeName = fileType.equals(1) ? "cer" : "sm2";
        try {
            tempFile = File.createTempFile("upload_tmp", "." + typeName);
        } catch (IOException e) {
            throw new ApplicationException(ErrorCodes.NOT_FOUND_FILE,"证书上传异常");
        }
        // 将上传文件内容写入临时文件
        try (InputStream inputStream = file.getInputStream();
             FileOutputStream fos = new FileOutputStream(tempFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }catch (Exception e){
            throw new ApplicationException(ErrorCodes.NOT_FOUND_FILE,"证书上传异常");
        }

        // 返回临时文件的完整路径
        return ActionResult.ok(tempFile.getAbsolutePath());
    }

2.根据前端传输的临时文件路径获取到文件并存到数据库

public static void main(String[] args) {
        Dto dto = new Dto();
        Merchant merchant = new Merchant();
        //存放证书
        Path carPath = Paths.get(dto.getMerCerFilePath());//jdk1.8之后可以用File.toPath()
        Path sm2Path = Paths.get(dto.getMerSm2FilePath());
        merchant.setMerCer(getCertFile(carPath));
        merchant.setMerSm2(getCertFile(sm2Path));

        save(merchant); //这里做插入或更新数据库操作

        //完成之后删除临时文件
        delCertFile(carPath);
        delCertFile(sm2Path);
    }

    /*********************************** private ***********************************/

    /**
     * 获取文件流
     * @param filePath 文件路径
     * @return 字节数组 对应实体类型为 private byte[] merCer; 数据库为blob类型
     */
    private byte[] getCertFile(Path filePath) {
        byte[] fileBytes;
        try {
            fileBytes =  Files.readAllBytes(filePath);
        } catch (IOException e) {
            throw new ApplicationException("无法读取文件字节流");
        }
        return fileBytes;
    }

    /**
     * 删除文件
     * @param filePath 文件路径
     */
    private void delCertFile(Path filePath) {
        try {
            Files.delete(filePath);
        } catch (IOException e) {
            log.error("删除临时文件异常:{}",e.getMessage());
        }
    }

3.注意实体属性类型(byte[])和数据库字段类型(blob)

1)实体属性类型

2)数据库字段类型

这样就可以把文件存入数据库~

二、读取和使用

1,查询数据库并根据文件流生成临时文件

    public static void main(String[] args) {
        Merchant merchant = merchantService.selectById(1);//查询对应渠道
        //获取到数据
        byte[] merCer = merchant.getMerCer();
        byte[] merSm2 = merchant.getMerSm2();

        TemFile cerTemFile = getTemFile(merCer, "cer");
        TemFile sm2TemFile = getTemFile(merSm2, "sm2");
        
        //使用
        String cerPath = cerTemFile.getTemFilePath();
        File cerFile = cerTemFile.getTemFile();
        String sm2Path = sm2TemFile.getTemFilePath();
        File sm2File = sm2TemFile.getTemFile();
        
        //...
        
        //使用完成之后删除临时文件
        if (cerTemFile.getCerFile() != null){
            cerTemFile.getCerFile().delete();
        }
        if (sm2TemFile.getSm2File() != null){
            sm2TemFile.getSm2File().delete();
        }
    }

    /**
     *
     * @param fileStream 从数据库读到的文件流
     * @param typeName 文件格式的后缀 例:cer , sm2
     * @return 返回对象对临时文件封装
     */
    public TemFileDto getTemFile(byte[] fileStream, String typeName) {
        TemFileDto temFileDto = new TemFileDto();

        File cerFile = null;
        try {
            cerFile = File.createTempFile("tmp", "." + typeName);
        } catch (IOException e) {
            log.error("获取证书异常:{}",e.getMessage());
        }
        try(InputStream cerInputStream = new ByteArrayInputStream(fileStream);
            FileOutputStream cerFileOutputStream = new FileOutputStream(cerFile);
                ) {
            cerFile = File.createTempFile("tmp", ".cer");
            byte[] target = fileStream;
            int bytesRead;
            while ((bytesRead = cerInputStream.read(target)) != -1) {
                cerFileOutputStream.write(target, 0, bytesRead);
            }
            temFileDto.setTemFilePath(cerFile.getAbsolutePath());
            temFileDto.setTemFile(cerFile);
        } catch (IOException e) {
            log.error("获取证书异常:{}",e.getMessage());
            throw new ApplicationException(ErrorCodes.NOT_FOUND_FILE,"获取证书异常");
        }
        return temFileDto;
    }

2.逻辑处理实体字段展示(Dto)

@Data
@ApiModel
public class TemFileDto {

    @ApiModelProperty(value = "临时文件路径")
    private String temFilePath;

    @ApiModelProperty(value = "临时文件")
    private File temFile;
}

到这里一整个的对于文件从存储到读取使用就已经结束啦~

欢迎留言,请多指教!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值