Servlet 3.0 使用request.part 处理文件上传

Servlet3.0 提供了比较简单的文件上传的api,今天自己写了一个,方便以后使用。

java code:

 

package org.vic.test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

//@MultipartConfig is necessary, we cannot get anything from request without it.
@MultipartConfig
public class UploadServlet extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static final String DIR = "D:/Users/upload";

	private static final String KEY = "fileKey";

	private static final String SUCCESS = "success";

	private static final String NONE = "none";

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			List<Future<Map<FileHelper, String>>> results = doUpload(req);
			if (results != null && results.size() > 0) {
				for (Future<Map<FileHelper, String>> future : results) {
					Map<FileHelper, String> map = future.get();
					String result = getResult(map);
					System.out.println(result);
				}
			} else {
				System.out.println("encountered an error!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}

	private String getResult(Map<FileHelper, String> map) {
		Set<Entry<FileHelper, String>> set = map.entrySet();
		Iterator<Entry<FileHelper, String>> it = set.iterator();
		while (it.hasNext()) {
			Entry<FileHelper, String> entry = it.next();
			FileHelper fileHelper = entry.getKey();
			String result = entry.getValue();
			String val = "file name: " + fileHelper.getFileName()
					+ "(Temporary id: " + fileHelper.getTempId()
					+ "), upload result: " + result;
			return val;
		}
		return NONE;
	}

	private List<Future<Map<FileHelper, String>>> doUpload(
			HttpServletRequest req) throws Exception {
		List<Future<Map<FileHelper, String>>> futures = new ArrayList<>();
		String key = null;
		Part p = req.getPart(KEY);
		if (p != null) {
			key = readInputStream(p.getInputStream());
		}
		if (key == null || "".equals(key)) {
			key = "file";
		}
		Collection<Part> parts = req.getParts();
		if (parts == null || parts.size() == 0) {
			return null;
		}
		ExecutorService threadPool = Executors.newCachedThreadPool();
		for (Part part : parts) {
			if (key.equals(part.getName())) {
				if (part.getSize() == 0) {
					continue;
				}
				String fileName = getFileName(part);
				UUID tempId = UUID.randomUUID();
				FileHelper fileHelper = new FileHelper(fileName, part, tempId);
				Future<Map<FileHelper, String>> future = threadPool
						.submit(new UploadTasker(fileHelper));
				futures.add(future);
			}
		}
		return futures;
	}

	private String readInputStream(InputStream in) throws IOException {
		StringBuffer buff = new StringBuffer();
		byte[] b = new byte[1024];
		int flag = 0;
		while ((flag = in.read(b)) != -1) {
			buff.append(new String(b, 0, flag));
		}
		return buff.toString();
	}

	private String getFileName(Part part) {
		String header = part.getHeader("Content-Disposition");
		String fileName = header.substring(header.indexOf("filename=\"") + 10,
				header.lastIndexOf("\""));
		header.lastIndexOf("\"");
		return fileName;
	}

	private class FileHelper {

		private String fileName;

		private Part part;

		private UUID tempId;

		public FileHelper(String fileName, Part part, UUID tempId) {
			this.fileName = fileName;
			this.part = part;
			this.tempId = tempId;
		}

		public String getFileName() {
			return fileName;
		}

		public Part getPart() {
			return part;
		}

		public UUID getTempId() {
			return tempId;
		}

	}

	private class UploadTasker implements Callable<Map<FileHelper, String>> {

		private FileHelper fileHelper;

		public UploadTasker(FileHelper fileHelper) {
			this.fileHelper = fileHelper;
		}

		@Override
		public Map<FileHelper, String> call() throws Exception {
			String fileName = fileHelper.getFileName();
			Part part = fileHelper.getPart();
			Map<FileHelper, String> returnMap = new HashMap<>();
			try {
				File file = new File(DIR);
				if (!file.exists()) {
					file.mkdirs();
				}
				String filePath = DIR + "/" + fileName;
				part.write(filePath);
				returnMap.put(fileHelper, SUCCESS);
			} catch (Exception e) {
				returnMap.put(fileHelper, e.getMessage());
			}
			return returnMap;
		}
	}
}

 

 

html code:  (在网上扒了一个,稍作了修改 尴尬)

 

<!DOCTYPE html>
<html>
    <head>
        <title>test</title>
        <!-- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -->
    </head>
    <body>
        <div>
            <form action="http://localhost:8080/UploadTest/upload.do" method="POST" enctype="multipart/form-data">
                <table>
                    <tr>
                        <td><label for="file1">文件1:</label></td>
                        <td><input type="file" id="file1" name="file"></td>
                    </tr>
                    <tr>
                        <td><label for="file2">文件2:</label></td>
                        <td><input type="file" id="file2" name="file"></td>
                    </tr>
                    <tr>
                        <td><label for="file3">文件3:</label></td>
                        <td><input type="file" id="file3" name="file"></td>
                    </tr>
                    <tr>
                        <td colspan="2"><input type="submit" value="上传" name="upload"></td>
                    </tr>
                </table>
                <input type="hidden" name="fileKey" value="file"/>
            </form>
        </div>
    </body>
</html>

 

 

 

 

 

 

SpringBoot文件上传报错Required request part ‘file‘ is not present深度排查指南 文件上传是Web开发中的基础功能,其核心原理基于HTTP协议中的multipart/form-data编码格式,该格式允许在单个请求中传输二进制数据和表单字段。在SpringBoot框架中,文件上传功能通过MultipartResolver组件实现,它负责解析请求中的文件部分并将其封装为MultipartFile对象。这一机制的技术价值在于简化了服务器端对文件数据的处理流程,提升了开发效率。然而,在实际工程实践中,开发者常会遇到文件上传失败的问题,典型的报错信息如Required request part 阅读详情

相关推荐

LED单元板驱动(HUB75接口)

开始之前先吐槽一下,搜这个的资料。要么都是Arduino,要么单片机的收费。小小的一个LED单元板,凭什么? 用Arduino是你速度快还是我ST,树莓派不好用?收费更离谱,这点东西还藏私?给你个中指凸。把原理都写出来看你怎么收费。 一、接口定义及原理 如图,有两个RGB通道,共占用6个IO。剩下的ABCDE为地址通道,LAT为行数据锁存通道,CLK为数据时钟,OE为低电平使能LED显示。图片这里没有E,证明它是16扫的,有E就会把B上面的地改为E。这样就是5位,2的5次方32扫。1.

a3748622的博客 3万+

使用Postman对@RequestPart和HttpServletRequest组合传参方式

想使用postman对entity和request参数传参,应该怎么传呢?

水巷石子的博客 4716

VMwareWorkstation安装UOS系统(1070版本)教程

UOS系统是一款国产信创操作系统。目前市面上主流的系统版本是1070,下面我们用虚拟机来安装一下这款系统。

欲买桂花同载酒的博客 4304

关于request.getPart()无法解析问题的解决办法

之前在调试程序的时候用的tomcat10,servlet4,结果在使用request.getPart的时候显示无法解析,没有办法使用。 后来查了很多资料,除开环境问题外,可以先打开相关的源码,查看是否存在这个方法。 当时使用的tomcat包里的servlet里就是找不到getPart这个方法,所以确定了就是tomcat包的问题,然后上官网重新下了一个,就可以使用了! ...

立志成为炼丹师? 3581

Unity开发HoloLens应用:从打包到部署的完整指南

本文为Unity开发者提供了将应用部署到HoloLens设备的完整实战指南。详细讲解了从环境准备、Unity项目配置、生成Visual Studio工程,到最终构建APPX安装包并通过设备门户或Visual Studio进行部署的全流程,帮助开发者高效完成混合现实应用的打包与安装。

red88的博客 1020

YOLOv8中Bottleneck模块详解

Bottleneck 模块在YOLOv8中的作用是进行特征提取和增强,是网络中的核心构建模块之一。它的主要功能是通过卷积操作来处理输入特征图,并在适当情况下应用残差连接,使得信息能够有效地通过网络层进行传播

zzzyyy8的博客 8067

httpservlet 中request部分功能

// getRequestURL方法 -- 返回客户端发出请求完整URL String url = request.getRequestURL().toString(); System.out.println("url: " + url); // getRequestURI方法 -- 返回请求行中的资源名部分 String uri = request.getRequestURI(); S...

qq_39486465的博客 293

实战|验证码突破思路

漏洞成因:由于逻辑设计缺陷,可绕过验证,比如直接删除COOKIE或验证码参数可绕过、当验证不通过清空session时,验证码参数值为空时绕过等。测试方法:抓包,删除验证码字段,查看是否可以成功发送抓包,正常流程下,记录验证码后的数据包,替换目标包中内容,直接发送,查看是否可以直接绕过验证码案例:Step1.输入正确账户信息和错误验证码,登录时抓包Step2.删除COOKIEStep3.客户端登陆成功。

weixin_46239998的博客 8106

JavaEE 使用Servlet上传文件

Servlet3.0提供了javax.servlet.http.Part类,通过它可以很方便的上传文件。

一直学,你始终是学生,但是只要创造一招,你便是宗师。 849

TCN(Temporal Convolutional Networks)时序卷积网络详解及代码

TCN(Temporal Convolutional Networks)时序卷积网络详解及代码

zhulewen的博客 7884

【云原生技术】helm中Chart.yaml、values.yaml、_helpers.tpl 各自的写法与作用

Chart.yaml、values.yaml、_helpers.tpl 各自的写法与作用 在一个标准的 Helm Chart 中,通常会包含以下关键文件: - **Chart.yaml** - **values.yaml** - **templates/`_helpers.tpl`** - 以及若干模板文件(`deployment.yaml`、`service.yaml` 等) 下面分别介绍这几个文件的作用、常见字段及其含义。

weixin_46453070的博客 754

@RequestPart注解的使用

当请求头中指定Content-Type:multipart/form-data时,传递的json参数,@RequestPart注解可以用对象来接收,@RequestParam只能用字符串接收。

qq_58148854的博客 3989

pytorch 51 GroundingDINO模型导出tensorrt并使用c++进行部署,53ms一张图

博主基于https://github.com/hpc203/GroundingDINO-onnxrun项目分享的onnx c++推理代码,修改为GroundingDINO模型的tensorrt推理代码。对于600x400的输入,在3060显卡下,cuda 12.1,TensorRT-10.4.0,window环境下53ms处理完一张图片。

a486259的博客 1221

java servlet 文件上传_java servlet 3.0文件上传

在以前,处理文件上传是一个很痛苦的事情,大都借助于开源的上传组件,诸如commons fileupload等。现在好了,很方便,便捷到比那些组件都方便至极。以前的HTML端上传表单不用改变什么,还是一样的multipart/form-dataMIME类型。让Servlet支持上传,需要做两件事情需要添加MultipartConfig注解从request对象中获取Part文件对象但在具体实践中,还...

weixin_39837207的博客 211

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Sevlet/JSP之一

2011-05-08 容器: 包含其他对象, 掌控对象生命周期(web容器, java的collection容器, EJB容器等) loadOnStartup大于0代表severlet在启动过程中即初始化, 数字越小, 优先级越高。 JSP编译为sevlet继承自HttpJspBase, 由jspwriter out写数据。 隐含对象: session, rquest, config, ou...

sheldon_sun的专栏 199

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Servlet3.0 新特性——HttpServletRequest 对文件上传的支持

此前,对于处理上传文件的操作一直是让开发者头疼的问题,因为 Servlet 本身没有对此提供直接的支持,需要使用第三方框架( commons-io + commons-fileupload )来实现,而且使用起来也不够简单。如今这都成为了历史,Servlet 3.0 已经提供了这个功能,而且使...

chuojiandi3387的博客 362

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Servlet 3.0 文件上传实战:基于 @MultipartConfig 注解的 5 步完整实现

本文详细介绍了Servlet 3.0中基于@MultipartConfig注解实现文件上传功能的完整步骤。从环境配置、注解参数解析到表单创建和Servlet实现,逐步指导开发者掌握高效安全的文件上传技术。特别针对Web程序设计中的常见需求,提供了文件类型验证、大小限制处理等最佳实践方案。

weixin_30378623的博客 396

在Servlet3.0中使用request.getParts()获取上传文件

Servlet3.0新增了request.getParts()/getPart(String filename) api,用于获取使用multipart/form-data格式传递的http请求的请求体,通常用于获取上传文件。   图片上传 window.onload = function(){ document.getElementById('fileUploader').

u012334071的专栏 4万+

Servlet 3.0 的文件上传功能

利用Servlet 3.0 的新特性可以轻松实现从客户端上传文件到服务器的功能。 原理:     首先介绍HttpServletRequest类中包含的涉及到文件上传的2个函数:     ① Part getPart(String name):根据文件名来获取文件上传域。      ② Collection getParts():获取所有文件的上传域。     上面两个方法的返回值都

<code> I am a coder </code> 885

Servlet处理文件上传

在Servlet3.0之前,form表单的文件上传需要接触common-fileupload等工具。 在Servlet3.0中,HttpServletRequest增加了对文件上传到的支持。 Http Servlet Request提供了如下两个方法来处理文件的上传:     Part getPart(String name):根据名称来获取文件上传域     Collection&lt;...

WARGON的博客 2806

上传文件如何从part对象中检索上传文件的文件名?_文件上传的方式

问题:JavaWeb中实现文件上传的方式有哪些?上回我们说了下文件下载的方式有哪些,这次我们从不同的环境下简单来说说文件上传的方式有哪些。文件上传的方式Servlet2.5 方式Servlet3.0 方式SpringMVC 方式案例实操Servlet2.5 方式文件上传涉及到前台页面的编写和后台服务器端代码的编写,前台发送文件,后台接收并保存文件,这才是一个完整的文件上传。1) 前台页面在做文件上...

weixin_36285931的博客 1920

Servlet3.0中HttpServletRequest增加了对文件上传的支持

Servlet3.0还有一个改变是改进了部分API,这种改进很好的简化了的了JAVA WEB的开发,其中一个改进就是HttpServletRequest增加了进文件上传的支持。   HttpServletRequest提供了如下两个方法来处理文件上传 1、Part getPart(String name) :根据文件名来获取文件上传域; 2、Collection getParts(

crazzy0727的专栏 1476

java getparts_servlet3.0 getPart()与getParts()获取上传文件

需求: servlet3.0以上,就是tomcat7.0以上,web.xml->web-app->version 3.0以上, 不需要引入其它的jar包Servlet类需要添加注释@MultipartConfig, 必要, 否则request.getPart()会为null@MultipartConfigpublicclassFileServletextendsHttpServ...

weixin_35645460的博客 848

java-基于Servlet3.0的文件上传

Servlet3.0学习总结(三)——基于Servlet3.0的文件上传 在Servlet3.0中使用request.getParts()获取上传文件

weixin_34015566的博客 152

Servlet3.0学习总结(三)——基于Servlet3.0的文件上传

Servlet3.0学习总结(三)——基于Servlet3.0的文件上传 在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileupload组件,在Servlet3.0中提供了对文件上传的原生支持,我们不需要借助任何第三方上传组件,直接使用Servlet3.0提供的API就能够实现文件上传功能了。 一、使用Servlet3....

weixin_30533797的博客 75

带你领略:Servlet 3.0新特性的奥秘!

在开发项目的过程中,我们经常会选择servlet 2.5。这时,我们知道:要使servlet对象正常的运行,需要进行适当的配置,以告知Web容器

weixin_44270855的博客 213
上一篇: 不用其他jar包,获取随机排列数组。
下一篇: compare local files and remote files.
vortex331
博客等级 码龄16年 0粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值