补充SpringMVC的文件上传以及文件下载
SpringMVC之文件上传以及文件下载
页面:
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="text" name="fName">
<input type="file" name="myFile">
<input type="submit" value="提交">
</form>
文件上传必备属性
enctype="multipart/form-data"
controller:
/**
* 文件上传
*/
@RequestMapping("/upload")
@ResponseBody
public Map<String, Object> upload(String fName, MultipartFile myFile) {
//定义一个返回值
HashMap<String, Object> map = new HashMap();
try {
//1.获取文件输入流
System.out.println(fName);
System.out.println(myFile);
InputStream is = myFile.getInputStream();
System.out.println(is);
String url = "F:\\Typora文件\\upload\\";
File file = new File(url + myFile.getOriginalFilename());
//文件输出流
OutputStream os = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
//文件边读边写
while ((len = is.read(bytes)) != -1) {
os.write(bytes);
}
//文件关闭流
os.close();
is.close();
//如果成功保存文件信息就返回一个成功的msg
map.put("msg", "保存成功");
} catch (IOException e) {
e.printStackTrace();
//如果出现异常情况就返回一个失败的msg
map.put("msg", "保存失败");
}
return map;
}
文件上传思路:
在服务端上传文件,是以文件流的形式进行的,所以得先获取文件的输入流(is),有了输入流就会有个输出流(os),输出流针对的参数那就是一个文件,所以我们得先new File文件。由于文件上传到客户端在磁盘中进行保存,而我们PC电脑既充当客户端,也充当服务端,所以我们可以在桌面创建一个文件夹,复制它的绝对路径url,然而我们上面new Flie文件的参数需要确定上传的文件的全路径,我们上传的所有形式的文件的全路径都基于我们桌面新建文件的url地址+上传文件的文件名+后缀,所以在new Flie对象中的参数为
url+myflie.getOriginalFilename
,后面的myflie.getOriginalFilename()方法可以直接获取到上传文件的文件名+后缀
。最后我们对输出的文件进行边读边写的操作,因为不知道我们上传的文件需要进行几次读写操作所以使用while循环,调用is.read()方法读取一个文件容器的字节大小
,每读一次就会返回一个长度值,只有长度不为-1
就会一直读下去知道长度为-1
,然后读一次就执行一次写文件的操作os.write(定义的文件容器的字节大小)
。
文件下载过程
我们在页面上指定下载资源<a href="/download?filename=dsb.jpg">资源下载</a>
后,还需要再Controller中编写我们将要进行的操作:
/**
* 文件下载
*/
而在链接中我们给了定了资源为dsb.jpg,我们在Controller中获取到后,还需要进行指定这个图片资源的位置在哪里。
// 创建输入流对象--读取磁盘文件
InputStream inputStream = new FileInputStream(file);
在指定完后,我们还需要进行判断文件资源是否存在。
// 指定提供资源的磁盘的目录
String dir="F:\\Typora文件\\SpringBoot\\img\\";
// 拼接该文件地址-判定该文件是否存在
File file = new File(dir + filename);
//进行判断是否存在
if (file.exists()){
....
}
在判断完成后若是存在,需要去读取磁盘中的文件,创建一个文件输出流。
// 创建一个获取文件输出流对象 可以看成FileOutputStream
ServletOutputStream outputStream = response.getOutputStream();
同时我们还需要返回响应头的,让浏览器可以返回下载框,并给其设置下载文件的名称:
// 指定文件的名称
response.setHeader("Content-Disposition","filename="+filename);
// 文件类型
response.setHeader("Content-Type","application/jpeg");
然后在读取下载资源并写入文件
//读取过程
byte []bytes=new byte[2048];
int len=0;
while ((len=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
遇到的问题
-
使用restful风格无法获取到我们我们所需的资源。 在路径上我们无法去读取
<a href="/download/dsb.jpg">资源下载</a>
到dsb.jpg的文件,会报一个406的错误。 -
获取资源类型的格式。
// 文件类型
response.setHeader("Content-Type","application/jpeg");
这里jpg格式的一般来说是要在找到相应的格式去进行下载,找到一个资源是:image/jpeg 使用这个格式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现