这是我参与更文挑战的第2天,活动详情查看:更文挑战
前言
在做的项目需要一个文件上传接口,上手就开撸了。写的过程中,遇到不少坑,在这里分享一下
环境
我的开发环境
| SpringBoot | 2.4.5 |
| Linux | Centos 7.5 |
| Java | 1.8 |
撸代码
Controller
注意使用 multipart/form-data
接收数据
@PostMapping(value="/upload",consumes = "multipart/*",headers = "content-type=multipart/form-data")
@ApiOperation(value = "上传图片",consumes = "multipart/form-data",produces = "multipart/form-data")
@ApiImplicitParam(name = "file", value = "文件", dataTypeClass = MultipartFile.class)
public ResultBean<Object> upload( @ApiParam(name = "file",value = "file", required = true) MultipartFile file) {
// 判断是否有文件
if (file.isEmpty()) {
return ResultBean.error(ResultEnum.NOT_FILE);
}
// 获取文件名
String originalFilename = file.getOriginalFilename();
// 获取文件后缀
String suffix = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
// 判断是不是可以接收的文件类型
// public final static String avatarFileSuffix = ".jpg.jpeg.png";
if (!FileSuffix.avatarFileSuffix.contains(suffix)) {
return ResultBean.error(ResultEnum.FILE_TYPE_ERROR);
}
// 用uuid作为新的文件名
String fileName = UUID.randomUUID() +"."+suffix;
try {
// 获取静态资源路径
File path = new File(ResourceUtils.getURL("classpath:").getPath());
if(!path.exists()){
path=new File("");
}
// 设置存放路径
File upload=new File(path.getAbsolutePath(),"static/images/upload/"+fileName);
// 如果目录不存在就创建目录
if(!upload.exists()){
upload.mkdirs();
}
// 写入
file.transferTo(upload);
return ResultBean.success("/images/upload/"+fileName);
} catch (IOException e) {
e.printStackTrace();
return ResultBean.error(ResultEnum.UPLOAD_ERROR);
}
}
OK 上传接口写完了,本地测试一下
这里使用的Swagger3 这种写法不能在swagger-ui中直接上传文件
写一个简单的html文件测试一下
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>单文件上传</title>
</head>
<body>
<form method="post" action="http://localhost:8090/upload" enctype="multipart/form-data">
<input type="file" name="file"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
还不错,够用了
选择文件,提交 OK 没有问题.访问也没有问题
然后上传到服务器运行 上传OK,访问......无法访问-显示找不到接口页面。我们后面解决这个问题
先说上传接口遇到的坑
坑
之前写的一版使用的相对路径结果报了异常 java.io.FileNotFoundException
需要使用绝对路径
Caused by: java.io.FileNotFoundException: /tmp/tomcat.8223985333111777969.80/work/Tomcat/localhost/ROOT/file:/project/xxx-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/static/images/upload/655acb70-c979-4ba4-b421-ca1c0d18bf1a.png (No such file or directory)
配置静态资源
注意 linux 不能解压 .jar 文件 无法像本地一样存在classes中,会存储在 jar 包的同级目录中
所以导致了第二个问题,虽然文件上传到了linux服务器 ,但是无法访问到这个文件
我们需要配置一下静态资源路径 static-locations
注意最后的 file:/root/public/static/
file 后面的就是文件上传后存储的位置
server:
resource:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:/root/public/static/