Ultra-detailed file uploads and downloads
Preface Ⅰ: The difference between @RequestParam and @RequestPart
@RequestPart
@RequestPart
This annotation is used onmultipart/form-data
the form submit request method.- The supported request method methods
MultipartFile
belong to the SpringMultipartResolver
class. This request ishttp协议
transmitted via
@RequestParam
@RequestParam
supportapplication/json
, as well as supportmultipart/form-data
requests
code demo
-
Test 1: Use @RequestPart to receive json data
Conclusion :
@RequestPart
can be convertedjsonData
tojson数据
Person对象
/** * 测试 RequestParam 和 RequestPart区别2 * @param person * @param file1 * @return * @throws IOException * @throws ServletException */ @RequestMapping(value = "/upload3",method = RequestMethod.POST) @ResponseBody public String readFile1(@RequestPart("person") Person person , @RequestPart("file1") MultipartFile file1) { StringBuilder sb = new StringBuilder(); sb.append(file1.getOriginalFilename()).append(";;;"); return person.toString() + ":::" + sb.toString(); }
parameter name parameter value Parameter Type file1 a file file person {"name":"cvzhanshi","age":23} application/json Test result: can use object to receive json
-
Test 2: Use @RequestParam to receive json data
Conclusion :
@RequestParam
forjsonData
only used tojson数据
receiveString字符串
/** * 测试 RequestParam 和 RequestPart区别2 * @param person * @param file1 * @return * @throws IOException * @throws ServletException */ @RequestMapping(value = "/upload3",method = RequestMethod.POST) @ResponseBody public String readFile1(@RequestParam("person") Person person , @RequestPart("file1") MultipartFile file1) { StringBuilder sb = new StringBuilder(); sb.append(file1.getOriginalFilename()).append(";;;"); return person.toString() + ":::" + sb.toString(); }
测试结果:报错 2022-10-08 10:19:48.434 WARN 3440 — [nio-8888-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type ‘java.lang.String’ to required type ‘cn.cvzhanshi.test.entity.Person’; nested exception is java.lang.IllegalStateException: Cannot convert value of type ‘java.lang.String’ to required type ‘cn.cvzhanshi.test.entity.Person’: no matching editors or conversion strategy found]
Error description: only receive and parse string type
difference (summary)
- Only values that can be received when the request is, can
multipart/form-data
receive complex request fields (like )@RequestParam
String类型
name-value
@RequestPart
json、xml
@RequestParam
DependConverter or PropertyEditor
on data analysis,@RequestPart
reference'Content-Type' header
, dependHttpMessageConverters
on data analysis- When Content-Type: multipart/form-data is specified in the request header, the passed json parameter, @RequestPart annotation can be received by object, @RequestParam can only be received by string
- @RequestParam is suitable for request fields of name-valueString type, and @RequestPart is suitable for complex request fields (like JSON, XML); the biggest difference between them is that when the request parameter type of the request method is no longer of String type
Preface Ⅱ: The difference between getParameter() and getPart()
code testing
/**
* 测试 RequestParam 和 RequestPart区别1
* @param request
* @param name
* @param file1
* @return
* @throws IOException
* @throws ServletException
*/
@RequestMapping(value = "/upload1",method = RequestMethod.POST)
@ResponseBody
public String readFile(HttpServletRequest request,@RequestParam("name") String name ,@RequestPart("file1") MultipartFile file1) throws IOException, ServletException {
String ageParameter = request.getParameter("age");
Part agePart = request.getPart("age");
String file2Parameter = request.getParameter("file2");
Part file2Part = request.getPart("file2");
Enumeration<String> parameterNames = request.getParameterNames();
Collection<Part> parts = request.getParts();
return "";
}
pass parameters
key | value | type |
---|---|---|
name | cvzhanshi | text |
age | 18 | text |
file1 | New text document.txt | file |
file2 | Beauty.jpg | file |
Debug analysis :
-
request : You can see that the request has two Parameter and two Part parameters
-
Parameter and Part : the value obtained by request.getParameter and the value obtained by request.getPart
It turns out that: using request.getParameter() to get the file type parameter is empty, and using request.getPart() to get the non-file type is empty
-
ParameterNames and Parts : getParameterNames() and getParts() get parameter names
Result: use request.getParameterNames() to get only non-file type parameter names, use request.getParts() to get all parameter names
in conclusion
- Part can get the parameter names of all request parameters, while Parameter can only get the parameter names of non-file types
- Part cannot obtain the parameter value of a non-file type parameter, and Part obtains a binary input stream
- Parameter can only get non-file type parameter values
- It is very convenient to use Part to get files, you can get the file size and file type
Ⅰ: File upload
① form-data type upload
The form-data type is a commonly used form submission, and there are two ways to receive files from the front end
- Receive the byte stream through the Part mentioned above, namely @RequestPart annotation and request.getParts()
- Receive files from the front end through the MultipartFile class
Explanation: The two methods are similar
Front-end interface submission
Backend code (interface) for uploading files
/**
* form-data 类型(前端表单上传)
* @param request
* @param name
* @param file3
* @param photo
* @return
* @throws IOException
* @throws ServletException
*/
@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 {
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{
// 可以获取文本参数值,文本参数 part.getContentType()为 null
System.out.println(request.getParameter(part.getName()));
}
}
return "success";
}
/**
* 字节流上传文件工具方法
* @param file
* @param path
* @return
*/
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() + " 上传成功";
} catch (Exception e) {
return file.getOriginalFilename() + " failed to upload ---> " + e;
}
} else {
return file.getOriginalFilename() + "You failed to upload file was empty.";
}
}
test
② Binary type upload
binary This type refers to some binary file types, such as application/pdf, which specifies the MIME type of a specific binary file. Just like for text file types if there is no specific subtype
(subtype), use text/plain. Similarly, binary files do not have a specific or known subtype, i.e. use application/octet-stream, which is the default for application files.
For application/octet-stream, only binary can be submitted, and only one binary can be submitted. If a file is submitted, only one file can be submitted. There can only be one receiving parameter in the background, and it can only be a stream
(or byte array)
Front-end interface submission
Backend code (interface) for uploading files
/**
* binary 类型上传
* @param request
* @return
* @throws IOException
*/
@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(path + "a.pdf"));
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 "上传成功";
}
test
Description: part is more convenient to use, it accepts byte stream, and it is more convenient to read file type, file name and file size
③ Configuration instructions
If you do not customize the configuration, he will upload the default size of 1M\
The SpringBoot project is configured through the configuration file
server:
port: 8888
spring:
servlet:
multipart:
max-file-size: 10MB # 最大上传大小
max-request-size: 100MB # 单文件最大上传大小
Ⅱ: File download
① Supplementary explanation
Content-Disposition
- In a regular HTTP response,
Content-Disposition
the response header indicates in what form the content of the response should be displayed, whether it is inline (that is, a web page or part of a page), or downloaded and saved locally as an attachment - In the response message body of multipart/form-data type,
Content-Disposition
the message header can be used in the subpart of the multipart message body to give relevant information of its corresponding field. Each subsection is separated by the delimiterContent-Type
defined in . It has no practical meaning when used in the message body itself.
Grammar :
-
As a message header in the message body : In the HTTP scenario, the first parameter is either
inline
(the default value, indicating that the message body in the reply will be displayed as a part of the page or the entire page), or (attachment
meaning the message body should be Download locally; most browsers will present a "Save As" dialog, prefilename
- filling the value of with the downloaded filename, if it exists).Content-Disposition: inline Content-Disposition: attachment Content-Disposition: attachment; filename="filename.jpg"
-
As a header in a multipart body : in an HTTP scenario. The first parameter is always fixed
form-data
; additional parameters are case-insensitive and have parameter values. The parameter name and parameter value are'='
connected with an equal sign ( ), and the parameter value is enclosed in double quotation marks. Parameters are separated by semicolons (';'
).Content-Disposition: form-data Content-Disposition: form-data; name="fieldName" Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"
The String parameter and corresponding type of response.setContentType()
file extension | Content-Type(Mime-Type) | file extension | Content-Type(Mime-Type) |
---|---|---|---|
.* (binary stream, unaware of download file type) | application/octet-stream | .tif | image/tiff |
.001 | application/x-001 | .301 | application/x-301 |
.323 | text/h323 | .906 | application/x-906 |
.907 | drawing/907 | .a11 | application/x-a11 |
.acp | audio/x-mei-aac | .ai | application/postscript |
.aif | audio/aiff | .aifc | audio/aiff |
.aiff | audio/aiff | .anv | application/x-anv |
.asa | text/so | .asf | video/x-ms-asf |
.asp | text/asp | .asx | video/x-ms-asf |
.au | audio/basic | .avi | I saw |
.awf | application/vnd.adobe.workflow | .biz | text/xml |
.bmp | application/x-bmp | .bot | application/x-bot |
.c4t | application/x-c4t | .c90 | application/x-c90 |
.cal | application/x-cals | .cat | application/vnd.ms-pki.seccat |
.cdf | application/x-netcdf | .cdr | application/x-cdr |
.The | application/x-cel | .cer | application/x-x509-ca-cert |
.cg4 | application/x-g4 | .cgm | application/x-cgm |
.cit | application/x-cit | .class | java/* |
.cml | text/xml | .cmp | application/x-cmp |
.cmx | application/x-cmx | .cot | application/x-cot |
.crl | application/pkix-crl | .crt | application/x-x509-ca-cert |
.csi | application/x-csi | .css | text/css |
.cut | application/x-cut | .dbf | application/x-dbf |
.dbm | application/x-dbm | .dbx | application/x-dbx |
.dcd | text/xml | .dcx | application/x-dcx |
.the | application/x-x509-ca-cert | .with | application/x-dgn |
.back | application/x-dib | .dll | application/x-msdownload |
.doc | application/msword | .dot | application/msword |
.through | application/x-drw | .dtd | text/xml |
.growth | Model/vnd.growth | .growth | application/x-dwf |
.dwg | application/x-dwg | .dxb | application/x-dxb |
.dxf | application/x-dxf | .edn | application/vnd.adobe.edn |
.emf | application/x-emf | .eml | message/rfc822 |
.ent | text/xml | .epi | application/x-epi |
.eps | application/x-ps | .eps | application/postscript |
.etd | application/x-ebx | .exe | application/x-msdownload |
.fax | image/fax | .fdf | application/vnd.fdf |
.fif | application/fractals | .fo | text/xml |
.frm | application/x-frm | .g4 | application/x-g4 |
.gbr | application/x-gbr | . | application/x- |
.gif | image/gif | .gl2 | application/x-gl2 |
.gp4 | application/x-gp4 | .hgl | application/x-hgl |
.hmr | application/x-hmr | .hpg | application/x-hpgl |
.hpl | application/x-hpl | .hqx | application/mac-binhex40 |
.hrf | application/x-hrf | .hta | application/hta |
.htc | text/x-component | .htm | text/html |
.html | text/html | .htt | text/webviewhtml |
.htx | text/html | .icb | application/x-icb |
.ico | image/x-icon | .ico | application/x-ico |
.iff | application/x-iff | .ig4 | application/x-g4 |
.igs | application/x-igs | .iii | application/x-iphone |
.img | application/x-img | .ins | application/x-internet-signup |
.isp | application/x-internet-signup | .IVF | video/x-ivf |
.java | java/* | .jfif | image/jpeg |
.jpe | image/jpeg | .jpe | application/x-jpe |
.jpeg | image/jpeg | .jpg | image/jpeg |
.jpg | application/x-jpg | .js | application/x-javascript |
.jsp | text/html | .la1 | audio/x-liquid-file |
.lar | application/x-laplayer-reg | .latex | application/x-latex |
.lavs | audio/x-liquid-secure | .lbm | application/x-lbm |
.lmsff | audio/x-la-lms | .ls | application/x-javascript |
.ltr | application/x-ltr | .m1v | video/x-mpeg |
.m2v | video/x-mpeg | .m3u | audio/mpegurl |
.m4e | video/mpeg4 | .mac | application/x-mac |
.man | application/x-troff-man | .math | text/xml |
.mdb | application/msaccess | .mdb | application/x-mdb |
.mfp | application/x-shockwave-flash | .mht | message/rfc822 |
.mhtml | message/rfc822 | .mi | application/x-mi |
.mid | audio/mid | .midi | audio/mid |
.mil | application/x-mil | .mml | text/xml |
.mnd | audio/x-musicnet-download | .mns | audio/x-musicnet-stream |
.mocha | application/x-javascript | .movie | video/x-sgi-movie |
.mp1 | audio/mp1 | .mp2 | audio/mp2 |
.mp2v | video/mpeg | .mp3 | audio/mp3 |
.mp4 | video/mpeg4 | .mpa | video/x-mpg |
.mpd | application/vnd.ms-project | .mpe | video/x-mpeg |
.mpeg | video/mpg | .mpg | video/mpg |
.mpga | audio/rn-mpeg | .mpp | application/vnd.ms-project |
.mps | video/x-mpeg | .mpt | application/vnd.ms-project |
.mpv | video/mpg | .mpv2 | video/mpeg |
.mpw | application/vnd.ms-project | .mpx | application/vnd.ms-project |
.mtx | text/xml | .mxp | application/x-mmxp |
.net | image/pnetvue | .nrf | application/x-nrf |
.nws | message/rfc822 | .odc | text/x-ms-odc |
.out | application/x-out | .p10 | application/pkcs10 |
.p12 | application/x-pkcs12 | .p7b | application/x-pkcs7-certificates |
.p7c | application/pkcs7-mime | .p7m | application/pkcs7-mime |
.p7r | application/x-pkcs7-certreqresp | .p7s | application/pkcs7-signature |
.pc5 | application/x-pc5 | .pci | application/x-pci |
.pcl | application/x-pcl | .pcx | application/x-pcx |
application/pdf | application/pdf | ||
.pdx | application/vnd.adobe.pdx | .pfx | application/x-pkcs12 |
.pgl | application/x-pgl | .pic | application/x-pic |
.pko | application/vnd.ms-pki.pko | .pl | application/x-perl |
.plg | text/html | .pls | audio/scpls |
.plt | application/x-plt | .png | image/png |
.png | application/x-png | .pot | application/vnd.ms-powerpoint |
.ppa | application/vnd.ms-powerpoint | .ppm | application/x-ppm |
.pps | application/vnd.ms-powerpoint | .ppt | application/vnd.ms-powerpoint |
.ppt | application/x-ppt | .pr | application/x-pr |
.prf | application/pics-rules | .prn | application/x-prn |
.prt | application/x-prt | .ps | application/x-ps |
.ps | application/postscript | .ptn | application/x-ptn |
.pwz | application/vnd.ms-powerpoint | .r3t | text/vnd.rn-realtext3d |
.ra | audio/vnd.rn-realaudio | .ram | audio/x-pn-realaudio |
.ras | application/x-ras | .rat | application/rat-file |
.rdf | text/xml | .rec | application/vnd.rn-recording |
.red | application/x-red | .rgb | application/x-rgb |
.rjs | application/vnd.rn-realsystem-rjs | .rjt | application/vnd.rn-realsystem-rjt |
.rlc | application/x-rlc | .rle | application/x-rle |
.rm | application/vnd.rn-realmedia | .rmf | application/vnd.adobe.rmf |
.rmi | audio/mid | .rmj | application/vnd.rn-realsystem-rmj |
.rmm | audio/x-pn-realaudio | .rmp | application/vnd.rn-rn_music_package |
.rms | application/vnd.rn-realmedia-secure | .rmvb | application/vnd.rn-realmedia-vbr |
.rmx | application/vnd.rn-realsystem-rmx | .rnx | application/vnd.rn-realplayer |
.rp | image/vnd.rn-realpix | .rpm | audio/x-pn-realaudio-plugin |
.rsml | application/vnd.rn-rsml | .rt | text/vnd.rn-realtext |
.rtf | application/msword | .rtf | application/x-rtf |
.rv | video/vnd.rn-realvideo | .sam | application/x-sam |
.sat | application/x-sat | .sdp | application/sdp |
.sdw | application/x-sdw | .sit | application/x-stuffit |
.slb | application/x-slb | .sld | application/x-sld |
.slk | drawing/x-slk | .smi | application/smil |
.smil | application/smil | .smk | application/x-smk |
.snd | audio/basic | .sol | text/plain |
.sor | text/plain | .spc | application/x-pkcs7-certificates |
.spl | application/futuresplash | .spp | text/xml |
.ssm | application/streamingmedia | .sst | application/vnd.ms-pki.certstore |
.stl | application/vnd.ms-pki.stl | .stm | text/html |
.sty | application/x-sty | .svg | text/xml |
.swf | application/x-shockwave-flash | .tdf | application/x-tdf |
.tg4 | application/x-tg4 | .tga | application/x-tga |
.tif | image/tiff | .tif | application/x-tif |
.tiff | image/tiff | .tld | text/xml |
.top | drawing/x-top | .torrent | application/x-bittorrent |
.tsd | text/xml | .txt | text/plain |
.uin | application/x-icq | .uls | text/iuls |
.vcf | text/x-vcard | .vda | application/x-vda |
.vdx | application/vnd.visio | .vml | text/xml |
.vpg | application/x-vpeg005 | .vsd | application/vnd.visio |
.vsd | application/x-vsd | .vss | application/vnd.visio |
.vst | application/vnd.visio | .vst | application/x-vst |
.vsw | application/vnd.visio | .vsx | application/vnd.visio |
.vtx | application/vnd.visio | .vxml | text/xml |
.wav | audio/wav | .wax | audio/x-ms-wax |
.wb1 | application/x-wb1 | .wb2 | application/x-wb2 |
.wb3 | application/x-wb3 | .wbmp | image/vnd.wap.wbmp |
.wiz | application/msword | .wk3 | application/x-wk3 |
.wk4 | application/x-wk4 | .wkq | application/x-wkq |
.wks | application/x-wks | .wm | video/x-ms-wm |
.wma | audio/x-ms-wma | .wmd | application/x-ms-wmd |
.wmf | application/x-wmf | .wml | text/vnd.wap.wml |
.wmv | video/x-ms-wmv | .wmx | video/x-ms-wmx |
.wmz | application/x-ms-wmz | .wp6 | application/x-wp6 |
.wpd | application/x-wpd | .wpg | application/x-wpg |
.wpl | application/vnd.ms-wpl | .wq1 | application/x-wq1 |
.wr1 | application/x-wr1 | .wri | application/x-wri |
.wrk | application/x-wrk | .ws | application/x-ws |
.ws2 | application/x-ws | .wsc | text/scriptlet |
.wsdl | text/xml | .wvx | video/x-ms-wvx |
.xdp | application/vnd.adobe.xdp | .xdr | text/xml |
.xfd | application/vnd.adobe.xfd | .xfdf | application/vnd.adobe.xfdf |
.xhtml | text/html | .xls | application/vnd.ms-excel |
.xls | application/x-xls | .xlw | application/x-xlw |
.xml | text/xml | .xpl | audio/scpls |
.xq | text/xml | .xql | text/xml |
.xquery | text/xml | .xsd | text/xml |
.xsl | text/xml | .xslt | text/xml |
.xwd | application/x-xwd | .x_b | application/x-x_b |
.sis | application/vnd.symbian.install | .sisx | application/vnd.symbian.install |
.x_t | application/x-x_t | .ipa | application/vnd.iphone |
.apk | application/vnd.android.package-archive | .xap | application/x-silverlight-app |
② Download local resources
download code
/**
* 下载本地资源
* @param fileName 下载的文件名
* @param response 响应头
* @param isOnLine 是否默认下载 true浏览器中打开
* @throws IOException
*/
@GetMapping("/download")
public void download(String fileName, HttpServletResponse response, boolean isOnLine) throws IOException {
// 路径可以指定当前项目相对路径
File file = new File(path + 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("背景.jpg", "utf8"));
}
byte[] bytes = new byte[1024];
int len;
// 把文件流写入响应头
while ((len = fileInputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
}
}
Test link: http://localhost:8888/download?fileName=background.jpg
Or http://localhost:8888/download?isOnLine=true&fileName=background.jpg
③ Download network resources
code demo
Explanation: You must first obtain the correct url to obtain the desired resource
/**
* 下载网络资源
* @param response
* @throws IOException
*/
@RequestMapping("/downLoadMusic")
public void downloadNetworkFile(HttpServletResponse response) throws IOException {
// 创建url对象
URL url = new URL("https://m701.music.126.net/20221009103058/70acd1fa2256e82ae0a90f833aec1072/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/18195365565/53a1/ad15/9e1c/1b3457995065a152f56f61c38eda1914.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"));
int len;
// 通过字节流下载下来
byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) != -1){
outputStream.write(bytes,0, len);
}
// 关闭资源
inputStream.close();
outputStream.close();
}
Test link: http://localhost:8888/downLoadMusic