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"

相关推荐
wuyunhang12345617 分钟前
Spring AOP概念及其实现
java·后端·spring
不思念一个荒废的名字21 分钟前
【黑马JavaWeb+AI知识梳理】后端Web基础01 - Maven
java·前端·maven
福理原乡大王28 分钟前
进程地址空间
java·开发语言·算法
南客先生1 小时前
音视频项目在微服务领域的趋势场景题深度解析
java·微服务·面试·性能优化·音视频·高并发
xcLeigh2 小时前
HTML5好看的水果蔬菜在线商城网站源码系列模板8
java·前端·html5
Alsn862 小时前
11.Spring Boot 3.1.5 中使用 SpringDoc OpenAPI(替代 Swagger)生成 API 文档
java·spring boot·后端
liyongjun63162 小时前
Java List分页工具
java·后端
猎人everest3 小时前
Spring Boot集成Spring Cloud 2024(不使用Feign)
java·spring boot·spring cloud
wangqiaowq3 小时前
防止HTTPS页面通过<iframe>标签嵌入HTTP内容
网络协议·http·https
茂桑3 小时前
日常开发小Tips:后端返回带颜色的字段给前端
java·状态模式