Java 文件上传与下载

Java 文件上传与下载MultipartFile这个类一般是用来接受前台传过来的文件Part能获取所有的请求参数的参数名,而Parameter只能获取非文件类型的参数名Part不能获得普通参数的参数值,只能从getParameter(String)获取参数值想要上传文件到服务器,必须使用Part获得二进制的输入流Part能获得上传文件的文件大小、文件类型HttpServletRequestrequest@RequestPart…

大家好,又见面了,我是你们的朋友全栈君。

Ⅰ、文件上传

一、form-data 类型

form-data 类型即常用的表单提交

两种处理参数的方式

  • MultipartFile 类接受前台传过来的文件
  • part 接收字节流

@RequestPart 作用类似 @RequestParam

1、postMan 请求

在这里插入图片描述

2、文件上传接口

直接上代码

@RestController
public class TestFile { 

private BufferedOutputStream bufferedOutputStream = null;
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String readFile(HttpServletRequest request, @RequestParam("name") String name, @RequestPart("file1") MultipartFile file3,@RequestPart("photo") MultipartFile photo) throws IOException, ServletException { 

String path= "I:\\spring\\spring-mybatis-plus\\src\\main\\resources\\public\\static\\";
System.out.println(name);
/* 第一种 : 使用 MultipartFile 封装好的 transferTo() 方法保存文件 photo.transferTo(new File(path+photo.getOriginalFilename())); 第二种 : 使用 MultipartFile 字节流保存文件 fileUtil(file3, String.valueOf(path)); 第三种 : 使用 Part 接收文件字节流 Part file2 = request.getPart("file2"); file2.write(path + file2.getSubmittedFileName()); */
// request.getParts() 获取的是全部参数(name,age,file1,file2),包括文件参数和非文件参数
for (Part part : request.getParts()) { 

// 获取文件类型
part.getContentType();
// 获取文件大小
part.getSize();
// 获取文件名
part.getSubmittedFileName();
// 获取参数名 (name,age,file1,file2)
part.getName()
if(part.getContentType()!=null){ 

part.write(path + part.getSubmittedFileName());
}else{ 

// 可以获取文本参数值
request.getParameter(part.getName())
}
}
return "success";
}
public String fileUtil(MultipartFile file, String path) { 

if (!file.isEmpty()) { 

try { 

byte[] bytes = file.getBytes();
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(
new File(path + file.getOriginalFilename())));
bufferedOutputStream.write(bytes);
bufferedOutputStream.close();
return file.getOriginalFilename() + "success upload";
} catch (Exception e) { 

return file.getOriginalFilename() + "failed to upload ---> " + e;
}
} else { 

return file.getOriginalFilename() + "You failed to upload file was empty.";
}
}
}

实际开发中,上面有很多需要优化的地方,比如写出文件工具类,获取项目路径(注意测试和打包上线路径),三种方法使用一种即可,流参数输出之后,就获取不到,不像其他参数可以在该请求的任意位置获取

如果一个输入框多个文件,可以使用

List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("");
// 也可以使用 part.getName() 获取参数名做判断
part.getName()

或者 MultipartFile[] file3

    public String readFile(HttpServletRequest request, @RequestParam("name") String name, @RequestPart("file1") MultipartFile[] file3) 
3、 测试

在这里插入图片描述

二、binary 类型

binary 这一类型,指的就是一些二进制文件类型,如application/pdf,指定了特定二进制文件的MIME类型。就像对于text文件类型若没有特定的子类型(subtype),就使用 text/plain。类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream,这是应用程序文件的默认值。

对于application/octet-stream,只能提交二进制,而且只能提交一个二进制,如果提交文件的话,只能提交一个文件,后台接收参数只能有一个,而且只能是流(或者字节数组)。

1、postMan 请求

在这里插入图片描述

2、文件上传接口

就是简单的文件读写,其中细节可以根据需求自行添加

@RequestMapping(value = "/upload2",method = RequestMethod.POST)
public String upload2(HttpServletRequest request) throws IOException { 

ServletInputStream inputStream = null;
FileOutputStream fileOutputStream = null;
try { 

inputStream = request.getInputStream();
fileOutputStream = new FileOutputStream(new File("I:\\spring\\spring-mybatis-plus\\src\\main\\resources\\public\\static\\微信图片_20210729130156.jpg"));
int len;
byte[] bytes = new byte[1024];
while((len = inputStream.read(bytes))!=-1){ 

fileOutputStream.write(bytes,0,len);
}
} catch (IOException e) { 

e.printStackTrace();
return "上传失败";
}
finally { 

if(fileOutputStream!=null){ 

fileOutputStream.close();
}
if(inputStream!=null){ 

inputStream.close();
}
}
return "上传成功";
}
3、测试

上传成功
在这里插入图片描述

三、springboot 配置

入股不配置,可能上传文件过大会保错,默认上传文件小于 1MB

如果是 springboot 项目,可以通过配置文件限制文件上传大小

文件上传配置类 MultipartAutoConfiguration
在这里插入图片描述
MultipartProperties 默认参数,可以看到默认开启,单个文件最大 1MB,单个请求最大 10MB
在这里插入图片描述
application.yml 上传文件配置

spring:
servlet:
multipart:
max-file-size: 10MB # 单个文件最大 10MB
maxRequestSize: 100MB # 单个请求最大 100 MB
四、总结

part 使用起来比较方便,接受的就是字节流,读取文件类型,文件名,文件大小也比较方便,不清楚 getParameter() 和 getPart() 区别 的可以看我另一篇博客
https://blog.csdn.net/qq_41538097/article/details/117637372

Ⅱ、文件下载

一、下载本地资源

Content-Disposition 详细说明:参考https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition
Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。
response.setHeader("Content-Disposition", "attachment;fileName=test.txt" ;
意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,将 filename 的值预填为下载后的文件名,假如它存在的话(fileName 或者 filename 都可以使用)
response.setHeader(“Content-Disposition”, “inline; filename=test.jpg” );设置为在线打开

public class FileDownload { 

@RequestMapping("/download")
public void download(String fileName, HttpServletResponse response,boolean isOnLine) throws IOException { 

// 路径可以指定当前项目相对路径
File file = new File("C:\\Users\\Administrator\\Pictures\\小程序\\" + fileName);
if (file.exists()) { 

FileInputStream fileInputStream = new FileInputStream(file);
ServletOutputStream outputStream = response.getOutputStream();
if(!isOnLine){ 

response.setContentType("application/octet-stream");
// 如果文件名为中文需要设置编码
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("test.jpg", "utf8"));
}
byte[] bytes = new byte[1024];
int len;
while ((len = fileInputStream.read(bytes)) != -1) { 

outputStream.write(bytes, 0, len);
}
}
}
}

测试下载:
接口:http://localhost:8081/download?fileName=test.jpg

不同的浏览器弹出的操作可能不同

chrome浏览器
在这里插入图片描述
IE浏览器
在这里插入图片描述
都可以下载成功
在这里插入图片描述
测试在线打开
http://localhost:8081/download?fileName=test.jpg&isOnLine=false
在这里插入图片描述
如果不指定下载,则默认是在线打开(谷歌浏览器)或者使用 response.setHeader(“Content-Disposition”, “inline; filename=test.jpg” );设置为在线打开

二、下载网络资源

到网易云音乐找个歌曲
在这里插入图片描述

    @RequestMapping("/downLoadMusic")
public void downloadNetworkFile(HttpServletResponse response) throws IOException { 

URL url = new URL("https://m701.music.126.net/20210808175335/c2ed0b504dd7bf3f86ac67a40fd092d2/jdyyaac/565b/065f/0358/a1cd0e25a815dffcc0c1422398efde9e.m4a");
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
ServletOutputStream outputStream = response.getOutputStream();
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("起风了.m4a", "utf8"));
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) { 

outputStream.write(bytes, 0, len);
}
outputStream.close();
inputStream.close();
}

chrome测试
在这里插入图片描述
IE测试
在这里插入图片描述

下载成功
在这里插入图片描述
注意:下面的情况针对静态资源在 resources 目录下,运行找不到资源的原因以及解决办法
首先,开发环境使用绝对路径肯定是不会错的,但部署运行环境就需要考虑路径问题,下面解决这个问题
对于 springboot 项目打成 jar 包,在 window/linux 系统使用 java -jar 运行时,需要考虑路径问题,因为是运行未解压 jar 包,如果直接指定 resources 目录下文件也运行是找不到的,此时必须使用输入流才可以 InputStream resourceAsStream = FileDownload.class.getClassLoader().getResourceAsStream("static/0.jpg"); 亲测对于 window/Linux 都有效
更多文件下载可参考 https://www.jb51.net/article/203861.htm

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/146360.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Jps命令—使用详解[通俗易懂]

    Jps命令—使用详解[通俗易懂]原文:https://blog.csdn.net/wisgood/article/details/38942449 jps是jdk提供的一个查看当前java进程的小工具,可以看做是JavaVirtualMachineProcessStatusTool的缩写。非常简单实用。    命令格式:jps[options][hostid]     [options…

  • idea 正则表达式替换「建议收藏」

    idea 正则表达式替换「建议收藏」例如,现在有一个函数getView(o,’m’,’orderNum’,’s’),这个函数的调用有很多地方,有一天我们想给这个函数加一个默认参数,让它变成getView(o,’m’,’orderNum’,’s’,’*’),一个一个加太麻烦了,我们就用idea自带的正则表达式替换功能来实现。首先按Ctrl+R,打开替换对话框,然后在上面输入getView\((.+)\),下面输…

  • 263企业邮箱在foxmail上的成功设置(smtpwcom/popwcom.xxoo.com)

    263企业邮箱在foxmail上的成功设置(smtpwcom/popwcom.xxoo.com)263企业邮箱在foxmail上设置了好几天,终于成功了!长话短说,我使用的263邮箱没有以@263.com结尾的(化名@xxoo.com结尾),设置时不管使用smtp/pop.xxoo.com还是使用smtpcom/popcom.xxoo.com都没用,后来中间加个w就有用

  • iview中 on-row-click 事件[通俗易懂]

    iview中 on-row-click 事件[通俗易懂]点击表格当前行 显示数据 <!– 给表格绑定on-row-click 事件 –> <Table :columns=”columns” :data=”list1″ @on-row-click=”showDetail”></Table>————————————————————————————————sho…

  • servlet到底是什么?[通俗易懂]

    servlet到底是什么?[通俗易懂]servlet到底是什么?对于这个问题一直云里雾里的,今天打算刨根问底。一、Servlet简介  Servlet是sun公司提供的一门用于开发动态web资源的技术。  Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:  1、编写一个Java类,实现servlet接口。

  • 数据结构–最小生成树详解[通俗易懂]

    数据结构–最小生成树详解[通俗易懂]前言Awisemanchangeshismind,afoolnever.Name:WillamTime:2017/3/11、什么是最小生成树现在假设有一个很实际的问题:我们要在n个城市中建立一个通信网络,则连通这n个城市需要布置n-1一条通信线路,这个时候我们需要考虑如何在成本最低的情况下建立这个通信网?于是我们就可以引入连通图来解决我们遇到的问题,n个城市就是图上的n

    2022年10月29日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号