Springboot中上传文件到Fdfs服务器

1.标题

  • 实际开发中经常会用到文件的上传和下载功能,如果是上传到本地有很多种方法,但是如果上传到Fdfs资源服务器就需要借助其他的工具类,现在比较火的就是开源工具com.github.tobato.fastdfs

2. 工具和实现

1.Maven中引入Jar包

 	<dependency>
        <groupId>com.github.tobato</groupId>
        <artifactId>fastdfs-client</artifactId>
        <version>1.26.2</version>
    </dependency>

2. 文件上传和下载实现类

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class AttachmentServiceImpl implements AttachmentService {

    @Autowired
    private AttachmentRepository attachmentRepository;
    // 注入工具类
    @Autowired
    private FastFileStorageClient fastFileStorageClient;
	/**
	  *  上传文件
	  */
    @Override
    public AttachmentVo uploader(MultipartFile file, String contentId) {

        //如果判断所属内容id为空,则生成一个并返回
        if (StringUtils.isBlank(contentId)) {
            contentId = UUIDUtils.newUUID().toString();
        }
        try {
        	// 获取文件名称
            String originalFilename = file.getOriginalFilename();
            Set<MataData> mataData = new HashSet<>(2);
            // 设置文件编码格式
            String fileName = URLEncoder.encode(originalFilename, "UTF-8");
            fileName = new String(fileName.getBytes("ISO-8859-1"), "UTF-8");
            // 将文件放入
            mataData.add(new MataData("fileName", fileName));
            log.debug("upload file with origin filename: {}", originalFilename);
            // 调用方法传入资源服务器中
            StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(),
                    FilenameUtils.getExtension(file.getOriginalFilename()), mataData);
          	// TODO 保存相关对象到数据库 并返回
          	return null;
        } catch (IOException e) {
            log.error("file upload failed with message: {}", e.getMessage());
            throw new StandardException("附件上传失败!");
        }
    }
    
	/**
	  *  查找文件
	  */
    @Override
    public List<AttachmentQueryVo> findByContentId(QueryAttachmentAction request) {
        String contentId = request.getContentId();
        List<AttachmentEntity> byContentId = attachmentRepository.findByContentId(contentId, DeletedType.NON);
        return BeanUtils.copyCollection(byContentId, AttachmentQueryVo.class);
    }
    
	/**
	  *  删除文件
	  */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteFile(DeleteAttachmentAction deleteAttachmentAction) {
        String id = deleteAttachmentAction.getId();
        Optional<AttachmentEntity> optional = attachmentRepository.findById(id);
        if (!optional.isPresent()) {
            throw new StandardException("附件未找到!");
        }
        AttachmentEntity attachmentEntity = optional.get();
        attachmentEntity.setDeleted(DeletedType.DEL);
        attachmentRepository.save(attachmentEntity);
        return true;
    }
    
	/**
	  *  下载文件
	  */
    @Override
    public void fileDownload(String id, String fullPath, HttpServletResponse response) {

        String group = "";
        String path = "";
        if (StringUtils.isBlank(id) && StringUtils.isBlank(fullPath)) {
            Assert.assertNotEmpty(id, "文件id或者url不能同时为空!");
        }
        // 如果ID为空 获取下载地址
        if (StringUtils.isNotBlank(id)) {
            AttachmentEntity entity = attachmentRepository.getOne(id);
            Assert.assertNotNull(entity, "附件未找到!");
            StorePath storePath = StorePath.praseFromUrl(entity.getDownloadUrl());
            group = storePath.getGroup();
            path = storePath.getPath();
        }
           // 如果ID和fullPath 都不为空  获取预览地址
        if (StringUtils.isBlank(id) && StringUtils.isNotBlank(fullPath)) {
            group = fullPath.substring(0, fullPath.indexOf("/"));
            path = fullPath.substring(fullPath.indexOf("/") + 1);

        }

        try {
        	// 根据地址获取资源服务器中的文件名称
            Set<MataData> set = fastFileStorageClient.getMetadata(group, path);
            String fileOriginName = set.stream().filter(mataData -> "fileName".equals(mataData.getName()))
                    .findFirst().orElse(new MataData("fileName", "文件名已丢失")).getValue();
            log.debug("download file with origin filename: {}", fileOriginName);
            response.setContentType("application/octet-stream");
            //设置导出编码格式
            response.setHeader("Content-disposition", "attachment;filename=" + fileOriginName + ";" + "filename*=utf-8''" + fileOriginName);
            OutputStream out = response.getOutputStream();
            String downloadResult = fastFileStorageClient.downloadFile(group, path, in -> {
                try {
                    IOUtils.copy(in, out);
                } catch (IOException e) {
                    log.error("download file failed: {}", e.getMessage());
                    return "failed!";
                } finally {
                    IOUtils.closeQuietly(in);
                    IOUtils.closeQuietly(out);
                }
                return "success!";
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3. 配置文件中配置

    fdfs:
	  so-timeout: 10000
	  connect-timeout: 30000
	  tracker-list: localhost:22122
	  pool:
	    max-total: 3000
	    max-wait-millis: 30000
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值