第2-3-4章 上传附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
目录
- 第2-1-2章 传统方式安装FastDFS-附FastDFS常用命令
第2-1-3章 docker-compose安装FastDFS,实现文件存储服务
第2-1-5章 docker安装MinIO实现文件存储服务-springboot整合minio-minio全网最全的资料全套代码及资料全部完整提供,点此处下载
5.3.1 接口文档
上传附件接口要完成的操作主要有两个:
- 将客户端提交的文件上传到指定存储位置(具体存储位置由配置文件配置的存储策略确定)
- 将上传的文件信息保存到数据库的pd_attachment表中
接口文档如下:
5.3.2 代码实现
第一步:创建AttachmentController并提供文件上传方法
package com.itheima.pinda.file.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.itheima.pinda.base.BaseController; import com.itheima.pinda.base.R; import com.itheima.pinda.file.dto.AttachmentDTO; import com.itheima.pinda.file.dto.AttachmentRemoveDTO; import com.itheima.pinda.file.dto.AttachmentResultDTO; import com.itheima.pinda.file.dto.FilePageReqDTO; import com.itheima.pinda.file.entity.Attachment; import com.itheima.pinda.file.service.AttachmentService; import com.itheima.pinda.utils.BizAssert; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; import static com.itheima.pinda.exception.code.ExceptionCode.BASE_VALID_PARAM; import static java.util.stream.Collectors.groupingBy; /** * 附件处理控制器 */ @RestController @RequestMapping("/attachment") @Slf4j @Api(value = "附件", tags = "附件") public class AttachmentController extends BaseController { @Autowired private AttachmentService attachmentService; /** * 上传附件 */ @ApiOperation(value = "附件上传", notes = "附件上传") @ApiImplicitParams({ @ApiImplicitParam(name = "isSingle", value = "是否单文件", dataType = "boolean", paramType = "query"), @ApiImplicitParam(name = "id", value = "文件id", dataType = "long", paramType = "query"), @ApiImplicitParam(name = "bizId", value = "业务id", dataType = "long", paramType = "query"), @ApiImplicitParam(name = "bizType", value = "业务类型", dataType = "long", paramType = "query"), @ApiImplicitParam(name = "file", value = "附件", dataType = "MultipartFile", allowMultiple = true, required = true), }) @PostMapping(value = "/upload") public R
upload( @RequestParam(value = "file") MultipartFile file, @RequestParam(value = "isSingle", required = false, defaultValue = "false") Boolean isSingle, @RequestParam(value = "id", required = false) Long id, @RequestParam(value = "bizId", required = false) String bizId, @RequestParam(value = "bizType") String bizType) { // 忽略路径字段,只处理文件类型 if (file.isEmpty()) { return fail(BASE_VALID_PARAM.build("请求中必须至少包含一个有效文件")); } AttachmentDTO attachment = attachmentService.upload(file, id, bizType, bizId, isSingle); return success(attachment); } } 第二步:创建AttachmentService接口
package com.itheima.pinda.file.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.itheima.pinda.file.dto.AttachmentDTO; import com.itheima.pinda.file.dto.AttachmentResultDTO; import com.itheima.pinda.file.dto.FilePageReqDTO; import com.itheima.pinda.file.entity.Attachment; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; /** * 附件业务接口 */ public interface AttachmentService extends IService
{ /** * 上传附件 * * @param file 文件 * @param id 附件id * @param bizType 业务类型 * @param bizId 业务id * @param isSingle 是否单个文件 * @return */ AttachmentDTO upload(MultipartFile file, Long id, String bizType, String bizId, Boolean isSingle); } 第三步:创建AttachmentServiceImpl实现类
package com.itheima.pinda.file.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.itheima.pinda.base.id.IdGenerate; import com.itheima.pinda.database.mybatis.conditions.Wraps; import com.itheima.pinda.database.mybatis.conditions.query.LbqWrapper; import com.itheima.pinda.dozer.DozerUtils; import com.itheima.pinda.exception.BizException; import com.itheima.pinda.file.dao.AttachmentMapper; import com.itheima.pinda.file.domain.FileDO; import com.itheima.pinda.file.domain.FileDeleteDO; import com.itheima.pinda.file.dto.AttachmentDTO; import com.itheima.pinda.file.dto.AttachmentResultDTO; import com.itheima.pinda.file.dto.FilePageReqDTO; import com.itheima.pinda.file.entity.Attachment; import com.itheima.pinda.file.entity.File; import com.itheima.pinda.file.enumeration.DataType; import com.itheima.pinda.file.properties.FileServerProperties; import com.itheima.pinda.file.service.AttachmentService; import com.itheima.pinda.file.strategy.FileStrategy; import com.itheima.pinda.utils.DateUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * 附件业务实现类 */ @Slf4j @Service public class AttachmentServiceImpl extends ServiceImpl
implements AttachmentService { @Autowired private IdGenerate idGenerate; @Autowired private DozerUtils dozer; @Autowired private FileStrategy fileStrategy; @Autowired private FileServerProperties fileProperties; /** * 上传附件 * * @param multipartFile 文件 * @param id 附件id * @param bizType 业务类型 * @param bizId 业务id * @param isSingle 是否单个文件 * @return */ @Override public AttachmentDTO upload(MultipartFile multipartFile, Long id, String bizType, String bizId, Boolean isSingle) { //根据业务类型来判断是否生成业务id if (StringUtils.isNotEmpty(bizType) && StringUtils.isEmpty(bizId)) { bizId = String.valueOf(idGenerate.generate()); } File file = fileStrategy.upload(multipartFile); Attachment attachment = dozer.map(file, Attachment.class); attachment.setBizId(bizId); attachment.setBizType(bizType); setDate(attachment); if (isSingle) { super.remove(Wraps. lbQ().eq(Attachment::getBizId, bizId).eq(Attachment::getBizType, bizType)); } if (id != null && id > 0) { //当前端传递了文件id时,修改这条记录 attachment.setId(id); super.updateById(attachment); } else { attachment.setId(idGenerate.generate()); super.save(attachment); } AttachmentDTO dto = dozer.map(attachment, AttachmentDTO.class); return dto; } private void setDate(Attachment file) { LocalDateTime now = LocalDateTime.now(); file.setCreateMonth(DateUtils.formatAsYearMonthEn(now)); file.setCreateWeek(DateUtils.formatAsYearWeekEn(now)); file.setCreateDay(DateUtils.formatAsDateEn(now)); } } 5.3.3 接口测试
第一步:启动Nacos配置中心,pd-file-server.yml配置内容如下:
pinda: mysql: database: pd_files nginx: ip: ${spring.cloud.client.ip-address} #正式环境要将该ip设置成nginx对应的公网ip port: 10000 #正式环境需要将该ip设置成nginx对应的公网端口 swagger: enabled: true docket: file: title: 文件服务 base-package: com.itheima.pinda.file.controller file: type: LOCAL # LOCAL ALI MINIO FAST_DFS local: uriPrefix: http://${pinda.nginx.ip}:${pinda.nginx.port} bucket-name: oss-file-service endpoint: D:\soft\nginx-1.23.0\uploadFiles ali: # 请填写自己的阿里云存储配置 bucket-name: bladex-loan endpoint: http://oss-cn-qingdao.aliyuncs.com access-key-id: LTAI4FhtimFAiz6iLGJSiJui access-key-secret: SsU15qaPwpF1x5xMqwc0XzGuY92fnc #FAST_DFS配置 fdfs: soTimeout: 1500 connectTimeout: 600 thumb-image: width: 150 height: 150 tracker-list: - 111.231.76.210:22122 pool: #从池中借出的对象的最大数目 max-total: 153 max-wait-millis: 102 jmx-name-base: 1 jmx-name-prefix: 1 server: port: 8765
第二步:启动Nginx服务
第三步:启动文件服务
第四步:访问接口文档,地址为http://localhost:8765/doc.html
可以看到上传的文件已经保存到了本地磁盘:
同时上传的文件信息也已经保存到了pd_attachment表中:
可以通过Nginx提供的Http服务来访问上传的文件:
http://192.168.137.3:10000//oss-file-service/2022/11/e76d3505-df38-4f95-a7bd-fb5de3ebe923.txt
全套代码及资料全部完整提供,点此处下载