HTTP:http上传文件的原理及java处理方法的介绍

为了说明原理,以下提供一个可以上传多个文件的例子,html页面代码如下:

html 复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>http upload file</title>
</head>
<body>
	<form action="/TestWeb/upload" method="post" enctype="multipart/form-data">
		<input type="text" name="uploadName1" id="uploadName1">
		<p />
		<input type="file" name="fileName1" id="file1">
		<p />
		<input type="text" name="uploadName2" id="uploadName2">
		<p />
		<input type="file" name="fileName2" id="file2">
		<p />
		<input type="submit" value="上传">
	</form>
</body>
</html>

显示效果如下:

通过点"浏览"选择要上传的文件,并分别输入保存时使用的文件名:

我们使用spring来处理上传的文件,代码如下:

java 复制代码
import java.io.IOException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class FileUploadController {

	@PostMapping("/upload")
	public String handleFormUpload(//
			@RequestParam("uploadName1") String uploadName1, //
			@RequestPart("fileName1") MultipartFile file1, //
			@RequestParam("uploadName2") String uploadName2, //
			@RequestPart("fileName2") MultipartFile file2) throws IOException {

		print(file1, uploadName1);

		System.out.println("+++++++++++++++");
		
		print(file2, uploadName2);

		return "redirect:upload";
	}

	private void print(MultipartFile file, String uploadName) throws IOException {
		String contentType = file.getContentType();
		String name = file.getName();
		String originalFilename = file.getOriginalFilename();
		long size = file.getSize();

		byte[] bytes = file.getBytes();

		System.out.println(uploadName);
		System.out.println(contentType);
		System.out.println(name);
		System.out.println(originalFilename);
		System.out.println(size);
		System.out.println(bytes.length);
	}
}

为了能使以上代码正常运行,还要做一些配置。比如,如果使用servlet3.0作为底层处理组件,还需要使用如下代码做配置:

java 复制代码
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {

        // Optionally also set maxFileSize, maxRequestSize, fileSizeThreshold
        registration.setMultipartConfig(new MultipartConfigElement("/tmp"));
    }

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return null;
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return null;
	}

	@Override
	protected String[] getServletMappings() {
		return null;
	}
}

点击"上传",打印日志如下:

report.txt

text/plain

fileName1

report.txt

31

31

+++++++++++++++

temp.txt

text/plain

fileName2

temp.txt

284

284

如果使用拦截工具,可以获取到如下上传报文:

POST /TestWeb/upload HTTP/1.1

Host: 127.0.0.1:9090

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate, br

Content-Type: multipart/form-data; boundary=---------------------------38678334721585548371903973726

Content-Length: 951

Origin: http://127.0.0.1:9090

Connection: keep-alive

Referer: http://127.0.0.1:9090/TestWeb/index.html

-----------------------------38678334721585548371903973726

Content-Disposition: form-data; name="uploadName1"

report.txt
-----------------------------38678334721585548371903973726

Content-Disposition: form-data; name="fileName1"; filename="report.txt"

Content-Type: text/plain

工作计划和工作总结

-----------------------------38678334721585548371903973726

Content-Disposition: form-data; name="uploadName2"

temp.txt
-----------------------------38678334721585548371903973726

Content-Disposition: form-data; name="fileName2"; filename="temp.txt"

Content-Type: text/plain

java.lang.IncompatibleClassChangeError:Expected non-static field org.springframework.web.reactive.result.method.InvocableHandlerMethod.logger
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.logArgumentErrorIfNecessary(InvocableHandlerMethod.java:207)

-----------------------------38678334721585548371903973726--

其中,黄色表示分隔线,绿色是上传的文件内容,蓝色是额外上传的文件名,红色是实际文件名。

通过打印的日志和拦截的报文,结合代码,就可以知道整个上传的处理过程。

以上是通过html页面上传文件,其实也可以不用页面也可以实现html上传,比如使用postman或curl。下面使用cur可以实现与html页面相同的功能:

curl -v http://127.0.0.1:9090/TestWeb/upload

-F "fileName1=@/D/Temp/temp.txt"

-F "uploadName1=temp.txt"

-F "fileName2=@/D/Temp/report.txt"

-F "uploadName2=report.txt"

相关推荐
大布布将军8 分钟前
⚡️编排的艺术:BFF 的核心职能——数据聚合与 HTTP 请求
前端·网络·网络协议·程序人生·http·node.js·改行学it
ALex_zry13 分钟前
现代C++如何解决传统内存分配器的核心痛点
java·c++·spring
Coder_Boy_15 分钟前
【人工智能应用技术】-基础实战-小程序应用(基于springAI+百度语音技术)智能语音控制-Java部分核心逻辑
java·开发语言·人工智能·单片机
MACKEI16 分钟前
业务域名验证文件添加操作手册
java·开发语言
roman_日积跬步-终至千里16 分钟前
【源码分析】StarRocks EditLog 写入与 Replay 完整流程分析
java·网络·python
apihz18 分钟前
货币汇率换算免费API接口(每日更新汇率)
android·java·开发语言
Web极客码19 分钟前
如何选择最适合的内容管理系统(CMS)?
java·数据库·算法
爱笑的眼睛1121 分钟前
Flask上下文API:从并发陷阱到架构原理解析
java·人工智能·python·ai
asdfg125896326 分钟前
数组去重(JS)
java·前端·javascript
别惹CC31 分钟前
Spring AI 进阶之路05:集成 MCP 协议实现工具调用
java·人工智能·spring