springboot实现上传文件与下载文件
一、 上传文件
1. 概述
springboot实现文件的上传,主要分为2种方式:1、通过数据库存取文件的url实现存取与读取2、通过数据库存取文件进行操作,下面我将主要讲述方式1
2. 代码实现
yml配置文件
file:
# 本地windows
#location: E:/idea-download/
#linux服务器
location: /usr/local/apps/pmxt-download/
path: /download/**
# domainname: http://43.142.87.68:9001
domainname: http://localhost:9001
location为服务器实际存储地址,path为通过URL地址的访问路径,两者是对应的
配置文件
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class FileDownloadConfig implements WebMvcConfigurer {
@Value("${file.location}")
String filelocation;
@Value("${file.path}")
String filepath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//匹配到resourceHandler,将URL映射至location,也就是本地文件夹
registry.addResourceHandler(filepath).addResourceLocations("file:///" + filelocation);//这里最后一个/不能不写
}
}
上述的配置文件也可以通过yml实现,如下图(web上级为spring):
这里主要是将服务器实际地址与URL对应
Controller
import com.example.pmxt.common.ReturnResult;
import com.example.pmxt.domain.Auctioneer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@RestController
@RequestMapping("/auctioneers")
@Validated
public class AuctioneerController {
//获取yml里配置好的变量
@Value("${file.location}")
String filelocation;
@Value("${file.path}")
String filepath;
@Value("${file.domainname}")
String domainname;
private final AuctioneerService auctioneerService;
@Autowired
public AuctioneerController(AuctioneerService auctioneerService) {
this.auctioneerService = auctioneerService;
}
@GetMapping()
public ReturnResult getauctioneerall(){
return ReturnResult.buildSuccessResult(auctioneerService.list());
}
@GetMapping("/{pmsbh}")
public ReturnResult getbypmsbh(@PathVariable @Validated String pmsbh){
Map<String,Object> map = new HashMap<>();
map.put("pmsbh",pmsbh);
return ReturnResult.buildSuccessResult(auctioneerService.listByMap(map));
}
@PostMapping()
public ReturnResult addauctioneer(@RequestBody @Validated Auctioneer auctioneer){
try {
// 获取文件名
String FileName = auctioneer.getPmszsz().substring(auctioneer.getPmszsz().lastIndexOf("/"));
// 复制文件
Files.copy(Paths.get(filelocation + "/auctioneer/temp/" + FileName), Paths.get(filelocation + "/auctioneer/" + FileName));
// 删除临时文件
Files.delete(Paths.get(filelocation + "/auctioneer/temp/" + FileName));
// 保存新的url
auctioneer.setPmszsz(auctioneer.getPmszsz().replace("/temp",""));
// 存入数据库
if(auctioneerService.save(auctioneer)){
return ReturnResult.buildSuccessResult(1);
}
else{
return ReturnResult.buildSuccessResult(0);
}
}
catch (IOException e){
return ReturnResult.buildFailureResult("logo/officialSeal 文件url不正确");
}
}
@DeleteMapping("/{id}")
public ReturnResult deletebyid(@PathVariable @Validated Integer id){
return ReturnResult.buildSuccessResult(auctioneerService.removeById(id));
}
@PutMapping()
public ReturnResult updateauctioneer(@RequestBody @Validated Auctioneer auctioneer){
return ReturnResult.buildSuccessResult(auctioneerService.updateById(auctioneer));
}
@PostMapping("/addpmszhz")
public ReturnResult addCarousel(MultipartFile file) {
if (file == null || file.isEmpty()) {
return ReturnResult.buildFailureResult("请传入文件");
} else {
try {
// 保存图片
// 服务器文件名
String serverFilename = UUID.randomUUID().toString().substring(0, 8)
+ file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
// 创建目录、存储图片地址目录
String path = filelocation + "/auctioneer/temp/";
// 存储图片的url
Files.createDirectories(Paths.get(path));
// 保存
file.transferTo(Path.of(path, serverFilename));
//这里是将URL返回给了前端,实际上也可以传到数据库,不过那样就其他的值也要一起传进来
return ReturnResult.buildSuccessResult(domainname + "/download/auctioneer/temp/" + serverFilename);
} catch (Exception e) {
e.printStackTrace();
return ReturnResult.buildFailureResult(e.toString());
}
}
}
}
二、下载文件
概述
一般来讲对于文件的下载只要给前端文件地址就好了,但是在修改jeecgboot框架时,发现文件只有PDF与图片格式能够打开并下载,而word与excel格式则无法打开下载,后来仔细查了一下,因为浏览器自带PDF与图片浏览插件,所以能够查看下载,而word与excel则只能下载,但是总是报401,token失效,后来仔细查了一下是因为前端把jeecgboot文件下载地址改了,由于没有在特定的地址下,所以受到了拦截器,而且token失效,但是当时以防万一自己也是写了个下载接口
导入依赖
// https://mvnrepository.com/artifact/commons-io/commons-io
implementation 'commons-io:commons-io:2.11.0'
写定下载静态方法
public static void downloadByCommonIO(String url, String saveDir, String fileName) {
try {
FileUtils.copyURLToFile(new URL(url), new File(saveDir, fileName));
} catch (IOException e) {
e.printStackTrace();
}
}
Controller接口
@PostMapping("/download")
public ReturnResult downloadFile(){
downloadByCommonIO("http://101.42.99.134:8888/jeecg-boot/sys/common/static/temp/46f630ac.xlsx","E:/桌面/新建文件夹","test.xlsx");
return ReturnResult.buildSuccessResult(true);
}
参考文档:https://blog.csdn.net/m0_46360888/article/details/128022927
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术