话不多说,直接上代码
1.必要jar包
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
2.controller代码
package com.cq.duty.controller.info;
import com.cq.base.common.BaseRequest;
import com.cq.base.common.BaseResult;
import com.cq.base.config.WebLogConfig;
import com.cq.base.entity.SysUser;
import com.cq.base.utils.RedisUserUtils;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* @Author: admin
* @Despriction:
* @Package: com.cq.duty.controller.info
* @Date:Created in 2021/1/27 9:24
* @Modify By:
*/
@RestController
@RequestMapping("/api/file")
@Api(tags = "附件管理相关接口")
@Slf4j
public class AttachmentController {
@Autowired
private RedisUserUtils redisUserUtils;
@Value("${attachment.path}")
private String basePath;
@Value("${server.port}")
private String port;
private static final String ATTACHMENT_PHOTO = "\\attachment\\photos";
private static final String ATTACHMENT_EXCEL = "\\attachment\\excels";
private static final String ATTACHMENT_WORD = "\\attachment\\words";
/**
* 文件上传
* @param file
* @param request
* @param sessionMultipartFile
* @return
* @throws Exception
*/
@PostMapping(value = "/upload")
public BaseResult fileUpload(@RequestParam(value = "file",required = false) MultipartFile file, HttpServletRequest request, HttpSession sessionMultipartFile) throws Exception {
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
MultipartFile multipartFile = multipartRequest.getFile("file");
if (multipartFile.isEmpty()) {
BaseResult.Error error = new BaseResult.Error("","上传文件失败,文件为空");
List<BaseResult.Error> errors = new ArrayList<>();
errors.add(error);
return BaseResult.ERROR(errors,"101");
}
String fileName = multipartFile.getOriginalFilename();
//截取文件后缀名
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
String path = "";
try {
// String currentPath = System.getProperty("user.dir");
// File fileDir = new File(currentPath);
// String parentPath = fileDir.getParent();
log.info("文件配置基础路径" + basePath);
if (StringUtils.contains("jpg,png,jepg",suffix)) {
File file1 = new File(basePath + ATTACHMENT_PHOTO);
file1.mkdirs();//创建目录,若目录存在也不会造成覆盖,而是追加
path = file1.getPath() + File.separator + fileName;
} else if (StringUtils.contains("xlsx,xls",suffix)) {
File file1 = new File(basePath + ATTACHMENT_EXCEL);
file1.mkdirs();
path = file1.getPath() + File.separator + fileName;
} else {
File file1 = new File(basePath + ATTACHMENT_WORD);
file1.mkdirs();
path = file1.getPath() + File.separator + fileName;
}
// 构建真实的文件路径
File newFile = new File(path);
log.info("第二次文件路径" + newFile.getAbsolutePath());
multipartFile.transferTo(newFile);
//http://localhost:8080/api/file/newFile.jpg
//本机IP地址
InetAddress addr = InetAddress.getLocalHost();
String urlPath = "http://" + addr.getHostAddress() + ":" + port + "/api/file/download/" + fileName;
return BaseResult.OK(urlPath,"200","上传附件成功");
} catch (Exception e) {
log.error("上传文件失败");
e.printStackTrace();
}
BaseResult.Error error = new BaseResult.Error("","上传文件失败");
List<BaseResult.Error> errors = new ArrayList<>();
errors.add(error);
return BaseResult.ERROR(errors,"101");
}
/**
* 文件下载 是以http方式进行访问
* eg:http://192.168.10.1:8080/api/file/download/test.png
* @param baseRequest
* @param request
* @param response
*/
@GetMapping("/download/{fileName}")
public void fileDownloadByHttp (@PathVariable String fileName,HttpServletRequest request, HttpServletResponse response) {
try {
// 取得文件的后缀名。
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
String path = "";
if (StringUtils.contains("jpg,png,jepg",suffix)) {
path = basePath + ATTACHMENT_PHOTO + File.separator + fileName;
} else if (StringUtils.contains("xlsx,xls",suffix)) {
path = basePath + ATTACHMENT_EXCEL + File.separator + fileName;
} else {
path = basePath + ATTACHMENT_WORD + File.separator + fileName;
}
// path是指欲下载的文件的路径。
File file = new File(path);
if (!file.exists()) {
throw new RuntimeException("文件不存在,下载失败");
}
// 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除文件
* @param baseRequest
* @return
*/
@PostMapping("/delete")
public BaseResult fileDelete (@RequestBody BaseRequest baseRequest) {
Object parameter = baseRequest.getParameter();
Map<String, Object> parametermap = new HashMap<>();
if (!Objects.isNull(parameter)) {
parametermap = (Map)parameter;
}
String path = (String) parametermap.get("path");
String fileName = path.substring(path.lastIndexOf("\\") + 1);
try {
// path是指欲下载的文件的路径。
File file = new File(path);
if (file.exists() && file.isFile()) {
file.delete();
return BaseResult.OK(null,"200","删除文件"+ fileName + "成功");
}
} catch (Exception e) {
e.printStackTrace();
}
BaseResult.Error error = new BaseResult.Error("","删除文件" + fileName + "失败");
List<BaseResult.Error> errors = new ArrayList<>();
errors.add(error);
return BaseResult.ERROR(errors,"101");
}
}
3.一些必要的描述
- 文件上传的时候以下代码是必须的
@RequestParam(value = "file",required = false) MultipartFile file
且必须通过以下代码才能获取得到上传文件的内容,否则 file会一直为null
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
MultipartFile multipartFile = multipartRequest.getFile("file");
上传接口使用postman进行调用测试时的使用方式,Headers处可以不用填任何参数,项目的token验证根据自己的项目要求来
2.文件下载时文件名必须设置字符集编码
URLEncoder.encode(filename, "UTF-8")
设置之后前端可以解码出正确的文件名称。不设置的话文件名就是一串??????号,尽管在postman中可能依然是乱码,但是此时的文件名是需要解码才能正常显示的。提供一个URL解码的工具网站可以参考:
http://tool.chinaz.com/tools/urlencode.aspx
3. 文件用java代码进行删除的时候,文件会被直接物理删除,连渣都不剩,回收站都找不到,因此进行此项操作时一定要考虑清楚,慎重操作。
删除操作可以参考以下博客,根据自己项目以作更改。
https://blog.youkuaiyun.com/kxj19980524/article/details/86693432