上传文件
一、Controller层
package com.sg.sgfinishedproductqualitymanage.controller;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sg.sgfinishedproductqualitymanage.common.ReturnData;
import com.sg.sgfinishedproductqualitymanage.pojo.TbFile;
import com.sg.sgfinishedproductqualitymanage.service.TbFileService;
import com.sg.sgfinishedproductqualitymanage.utils.UUIDUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Api(tags = "文件上传相关接口")
@RestController
@RequestMapping({"/file"})
public class FileController {
@Value("${files.upload.path}")
private String fileUploadPath;
@Autowired
private TbFileService fileService;
@ApiOperation("文件上传")
@PostMapping("/upload")
@Transactional
public ReturnData upload(@RequestBody MultipartFile file, HttpServletRequest request) throws IOException {
System.out.println(file);
//获取原始文件名称
String originalFilename = file.getOriginalFilename();
//通过hutool工具包获取文件类型
String type = FileUtil.extName(originalFilename);
//获取文件大小
long size = file.getSize();
//先存到磁盘
File uploadParentFile = new File(fileUploadPath);
//判断文件目录是否存在,不存在则新建
if (!uploadParentFile.exists()) {
if (!uploadParentFile.getParentFile().exists()){
uploadParentFile.getParentFile().mkdirs();
}
uploadParentFile.mkdir();
}
//配置文件的唯一标识位
String uuid = IdUtil.fastSimpleUUID();
//文件名设置
String fileUuid = uuid + StrUtil.DOT + type;
File uploadFile = new File(fileUploadPath + fileUuid);
//当文件存在的时候再获取文件MD5
String url;
//把获取到的文件存到磁盘目录中去
file.transferTo(uploadFile);
//获取文件MD5
String md5 = SecureUtil.md5(uploadFile);
TbFile fileMd5 = getFileMd5(md5);
if (fileMd5!=null){
//如果不为空
url = fileMd5.getUrl();
uploadFile.delete();
}else {
//String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
url = "http://h5.shasteel.cn/h5/test/file/" + fileUuid;
}
//存储到数据库
QueryWrapper<TbFile> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name",originalFilename);
TbFile one = fileService.getOne(queryWrapper);
if (null==one){
TbFile tbFile = new TbFile();
tbFile.setPkId(UUIDUtils.getUUID());
tbFile.setFileName(originalFilename);
tbFile.setFileType(type);
tbFile.setFileSize(size/1024);
tbFile.setMd5(md5);
tbFile.setUrl(url);
fileService.save(tbFile);
}
return ReturnData.success(url,null);
}
@ApiOperation("多文件上传")
@PostMapping("/uploads")
@Transactional
public ReturnData uploads(@RequestParam("files")MultipartFile[] files, HttpServletRequest request) throws IOException {
List<String> urls = new ArrayList<>();
System.out.println(files);
for (MultipartFile file:files){
System.out.println(file);
//获取原始文件名称
String originalFilename = file.getOriginalFilename();
//通过hutool工具包获取文件类型
String type = FileUtil.extName(originalFilename);
//获取文件大小
long size = file.getSize();
//先存到磁盘
File uploadParentFile = new File(fileUploadPath);
//判断文件目录是否存在,不存在则新建
if (!uploadParentFile.exists()) {
if (!uploadParentFile.getParentFile().exists()){
uploadParentFile.getParentFile().mkdirs();
}
uploadParentFile.mkdir();
}
//配置文件的唯一标识位
String uuid = IdUtil.fastSimpleUUID();
//文件名设置
String fileUuid = uuid + StrUtil.DOT + type;
File uploadFile = new File(fileUploadPath + fileUuid);
//当文件存在的时候再获取文件MD5
String url;
//把获取到的文件存到磁盘目录中去
try {
file.transferTo(uploadFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
//获取文件MD5
String md5 = SecureUtil.md5(uploadFile);
TbFile fileMd5 = getFileMd5(md5);
if (fileMd5!=null){
//如果不为空
url = fileMd5.getUrl();
uploadFile.delete();
}else {
/*String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();*/
url = "http://h5.shasteel.cn/h5/test/file/" + fileUuid;
}
//存储到数据库
TbFile one = fileService.selectByName(originalFilename);
if (null==one){
TbFile tbFile = new TbFile();
tbFile.setPkId(UUIDUtils.getUUID());
tbFile.setFileName(originalFilename);
tbFile.setFileType(type);
tbFile.setFileSize(size/1024);
tbFile.setMd5(md5);
tbFile.setUrl(url);
fileService.save(tbFile);
}
urls.add(url);
};
return ReturnData.success(urls,null);
}
/**
* 通过文件的MD5查询文件
* @param md5
* @return
*/
private TbFile getFileMd5(String md5) {
List<TbFile> list = fileService.queryMD5(md5);
return list.size() == 0 ? null : list.get(0);
}
}
二、实体类
package com.sg.sgfinishedproductqualitymanage.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
/**
* 文件
* @TableName TB_FILE
*/
@TableName(value ="TB_FILE")
public class TbFile implements Serializable {
/**
* 主键
*/
@TableId
private String pkId;
/**
* 文件名
*/
private String fileName;
/**
* 文件类型
*/
private String fileType;
/**
* 文件大小
*/
private Long fileSize;
/**
* 文件访问链接
*/
private String url;
/**
* 文件唯一
*/
private String md5;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/**
* 主键
*/
public String getPkId() {
return pkId;
}
/**
* 主键
*/
public void setPkId(String pkId) {
this.pkId = pkId;
}
/**
* 文件名
*/
public String getFileName() {
return fileName;
}
/**
* 文件名
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* 文件类型
*/
public String getFileType() {
return fileType;
}
/**
* 文件类型
*/
public void setFileType(String fileType) {
this.fileType = fileType;
}
/**
* 文件大小
*/
public Long getFileSize() {
return fileSize;
}
/**
* 文件大小
*/
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
/**
* 文件访问链接
*/
public String getUrl() {
return url;
}
/**
* 文件访问链接
*/
public void setUrl(String url) {
this.url = url;
}
/**
* 文件唯一
*/
public String getMd5() {
return md5;
}
/**
* 文件唯一
*/
public void setMd5(String md5) {
this.md5 = md5;
}
}
三、yml文件相关配置(文件保存路径)。
files:
upload:
path: D:/mytest/travel/file/
四、访问已上传的图片返回的url,需要进行配置类编写
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 解决跨域问题
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Value("${file.upload.file}")
private String staticFilePath;//yml中配置的文件存储路径
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
/**
* 配置文件读取
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//配置swagger-dom.html
registry.addResourceHandler("dom.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
//配置文件上传返回url访问问题
registry.addResourceHandler("/file/**").addResourceLocations("file:" + staticFilePath);
}
}
五、Swagger配置
1.依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
<version>3.0.3</version>
</dependency>
2.配置类
package com.sg.sgfinishedproductqualitymanage.config;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Configuration
public class SpringFoxSwaggerConfig {
/**
* 配置基本信息
*
* @return
*/
@Bean
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("抚顺检化验")
.description("抚顺检化验手机app")
.termsOfServiceUrl("http://localhost:8989/doc.html#/home")
.contact(new Contact("CC", "https://blog.youkuaiyun.com/CC_Waiting?type=blog", "10062906@qq.com"))
.version("1.0")
.build();
}
/**
* 配置文档生成最佳实践
*
* @param apiInfo
* @return
*/
@Bean
public Docket createRestApi(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo)
.groupName("SwaggerGroupOneAPI")
.select()
.apis(RequestHandlerSelectors.basePackage("com.fs.shasteel.controller"))
.paths(PathSelectors.any())
.build();
}
/**
* 增加如下配置可解决Spring Boot 6.x 与Swagger 3.0.0 不兼容问题
**/
@Bean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
allEndpoints.addAll(webEndpoints);
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
String basePath = webEndpointProperties.getBasePath();
EndpointMapping endpointMapping = new EndpointMapping(basePath);
boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
}
private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
}
}
3.启动类上注解
@EnableWebMvc
六、swagger升级,设置swagger访问密码
1.更换依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
2.在application.yml中配置访问密码
knife4j:
enable: true
basic:
enable: true
username: admin
password: 123456