@MultipartConfig注解
前言:
在学习Javaweb的Servlet文件上传和下载的过程中,我们会遇到一个特殊的注解---@MultipartConfig。
@MultipartConfig的适用情况:
1.文件上传: 当您的应用程序需要接收用户上传的文件时,可以在相应的 Servlet 上使用 @MultipartConfig 注解。通过使用该注解Servlet 可以方便地解析和处理 multipart/form-data 类型的请求,从中提取上传的文件。
2.图片上传: 如果您的应用程序需要用户上传图片,例如头像、照片等,那么您可以使用 @Multipartconfig 注解来处理包含图片文件的表单请求。
3.多媒体内容:如果您的应用程序需要处理包含音频、视频或其他多媒体内容的表单请求,您可以使用 @Multipartconfig 注解来处理这些请求并提取相应的多媒体文件。
4.表单中的大量数据:有时,表单中可能包含大量的字段和数据。在这种情况下,@Multipartconfig 注解可以帮助您处理这些复杂的表单请求。
以上也许您不想花大量的时间来阅读,那么我就用一句简单的话来解释:
当您的应用程序需要处理包含文件或其他二进制数据的表单请求时,可以使用 @MultipartConfig
注解。它使得解析和处理 multipart/form-data
请求变得更加简单和方便。
了解完@MultipartConfig注解的适用情况。接下来还是来看看API文档的描述吧。
API文档内容:
翻译过来就是:
@MultipartConfig
注解可以应用于 Servlet 类上,用于指示该 Servlet 预期符合 multipart/form-data
MIME 类型的请求。这通常用于处理包含文件上传的表单数据。
当一个 Servlet 使用了 @MultipartConfig
注解后,它可以通过调用 getPart
或 getParts
方法来获取给定 multipart/form-data
请求的各个部分(Part 组件)。Part 组件代表了上传的文件或其他表单字段的数据。
当然,这个注解还有一些属性,如下:
这里不过多展开这些属性,只需要知道它有这几个属性:
1.fileSizeThreshold
(文件大小阈值):指定文件在超过该大小阈值后将被写入磁盘
2.location
(文件存储目录):指定文件将存储的目录位置。上传的文件将被存储在该指定的目录中
3.maxFileSize
(最大文件大小):指定允许上传的单个文件的最大大小
4.maxRequestSize
(最大请求大小):指定允许的 multipart/form-data 请求的最大大小。
实例测试:
那么还是先来看一下正常的代码与运行结果吧!
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><link href = "Book_entry.css" rel="stylesheet" type = "text/css" /><title>图书录入系统</title>
</head>
<body>
<!--书籍名称、出版社、编者、价格、书籍介绍--><h2>图书录入</h2>
<div><form enctype="multipart/form-data" method="post" action="../Book_entry"><label for = "book_name">书籍名称: </label><br><input type = "text" id = "book_name" name = "book_name" placeholder="请输入书籍名称"><br><br><label for = "publishing_house">出版社: </label><br><input type = "text" id = "publishing_house" name = "publishing_house" placeholder="请输入出版社"><br><br><label for = "editor">编者: </label><br><input type = "text" id = "editor" name = "editor" placeholder="请输入编者"><br><br><label for = "Price">价格: </label><br><input type = "text" id = "Price" name = "Price" placeholder="请输入价格"><br><br><p><input type="checkbox" value = "social_science" name = "Book_type" checked/>社会科学<input type="checkbox" value = "natural_science" name = "Book_type" />自然科学<input type="checkbox" value = "philosophy" name = "Book_type" />哲学<input type="checkbox" value = "novel" name = "Book_type" />小说<input type="checkbox" value = "art" name = "Book_type" />艺术</p><label>书籍介绍: </label><br><textarea name="description"></textarea><br><br><input type = "file" id = "photo" name = "photo" placeholder="请插入图片"><input type="submit" value="提交"></form>
</div></body>
</html>
package com.example;import com.example.Book;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;@MultipartConfig
@WebServlet("/Book_entry")public class BookServlet extends HttpServlet {private List<Book> books = new ArrayList<>();@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("utf-8");// 从请求参数中获取书籍信息String book_name = request.getParameter("book_name");String publishing_house = request.getParameter("publishing_house");String editor = request.getParameter("editor");String Price = request.getParameter("Price");String bookType = request.getParameter("Book_type");String description = request.getParameter("description");//获取上传的Part对象Part photo = request.getPart("photo");StringBuffer sb = new StringBuffer();if(book_name.isBlank())sb.append("必须输入书名");else if(publishing_house.isBlank())sb.append("必须输入出版社");else if(editor.isBlank())sb.append("必须输入作者");else if(Price.isBlank())sb.append("必须输入价格");else if(bookType.isBlank())sb.append("必须输入书的类型");else if(description.isBlank())sb.append("必须输入书籍介绍");else if(photo == null)sb.append("必须上传书的封面");// if(sb.length() != 0)
// {
// response.getWriter().println(sb);
// return;
// }
// sb.append("书名:").append(book_name).append("<br>");
// sb.append("出版社:").append(publishing_house).append("<br>");
// sb.append("作者:").append(editor).append("<br>");
// sb.append("价格:").append(Price).append("<br>");
// sb.append("书类型:").append(bookType).append("<br>");
// sb.append("书籍介绍:").append(description).append("<br>");//断言assert photo != null;InputStream is = photo.getInputStream();ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] b = new byte[1024];while(is.read(b)>0){baos.write(b);}b = baos.toByteArray();UUID uuid = UUID.randomUUID();String sfn = photo.getSubmittedFileName();String suffix = sfn.substring(sfn.lastIndexOf("."));FileOutputStream fos = new FileOutputStream("D:/photo/" + uuid.toString() + suffix);fos.write(b);fos.close();String imageUrl = "D:/photo/" + uuid.toString() + suffix;// 创建Book对象Book book = new Book();book.setTitle(book_name);book.setPublisher(publishing_house);book.setEditor(editor);book.setPrice(Price);book.setDescription(description);// 将书籍信息添加到列表中books.add(book);// 返回成功信息response.setContentType("text/html;charset=utf-8");response.getWriter().println(sb);String head = """<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>图书信息</title><link href = "./Book_entry.css" rel="stylesheet" type = "text/css"/></head><body>""";head += "<h3 style=\"text-align:center\">图书信息</h3>";head += "<div>";head += "<p>书名:" + book_name + "</p>";head += "<p>出版社:" + publishing_house + "</p>";head += "<p>编辑:" + editor + "</p>";head += "<p>价格:" + Price + "</p>";head += "<p>书籍类型:" + bookType + "</p>";head += "<p>描述:" + description + "</p>";head += "<img src=\"D:/photo/" + uuid.toString() + suffix + "\" alt=\"书籍封面\">";head += "</div>";response.getWriter().println(head);}
}
以上便是代码部分
那么来看一下运行的结果!
代码是正常运行的!
但是!!!如果我们去掉@MultipartConfig的注解呢?
我们发现:从html页面获取的内容为null
调试结果也告诉我们:book_name为空了
那么原因如下:
如果你在处理包含文件上传的multipart/form-data
类型的请求时没有添加@MultipartConfig
注解,request.getParameter()
方法无法直接获取文本框(<input type="text">
)中的内容,而会返回null
。
这是因为在multipart/form-data
类型的请求中,表单数据包含了文件和其他文本字段,而request.getParameter()
方法只能用于获取application/x-www-form-urlencoded
编码类型的表单参数值,不能直接获取multipart/form-data
类型请求中的文本字段的值。
当使用@MultipartConfig
注解配置Servlet来处理multipart/form-data
请求时,Servlet容器会根据该注解的配置,自动解析请求中的文件和文本字段,并将它们作为Part
对象提供给开发者使用。
要获取multipart/form-data
请求中的文本字段的值,你可以使用request.getPart()
方法来获取对应的Part
对象,然后通过Part
对象的getInputStream()
方法读取文本字段的内容。
相关文章:

@MultipartConfig注解
前言: 在学习Javaweb的Servlet文件上传和下载的过程中,我们会遇到一个特殊的注解---MultipartConfig。 MultipartConfig的适用情况: 1.文件上传: 当您的应用程序需要接收用户上传的文件时,可以在相应的 Servlet 上使用 Multipart…...

Python并发编程简介
1、Python对并发编程的支持 多线程: threading, 利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成多进程: multiprocessing, 利用多核CPU的能力,真正的并行执行任务异步IO: asyncio,在单线程利用CPU和IO同时执行的原理,实现函数异步执行使用Lo…...
WebSocket介绍及部署
WebSocket是一种在单个TCP连接上进行全双工通信的协议,其设计的目的是在Web浏览器和Web服务器之间进行实时通信(实时Web)。 WebSocket协议的优点包括: 1. 更高效的网络利用率:与HTTP相比,WebSocket的握手…...

自动求导,计算图示意图及pytorch实现
pytorch实现 x1 torch.tensor(3.0, requires_gradTrue) y1 torch.tensor(2.0, requires_gradTrue) a x1 ** 2 b 3 * a c b * y1 c.backward() print(x1.grad) print(y1.grad) print(x1.grad 6 * x1 * y1) print(y1.grad 3 * (x1 ** 2))输出为: tensor(36.) …...
睿伴科创上线了
Robotutor睿伴,一个专业的青少儿编程科创教育品牌和科创服务平台。 Robotutor睿伴拥有一个超过5年的青少儿编程科创教育团队,积累了丰富的课程研发,教学服务和赛事辅导经验。并和上海多所知名高校、上海市计算机学会、上海青少年科学社等开展…...
域名抢注和域名注册
随着互联网的发展,域名已经成为了企业和个人在网络上展示自己的重要标志。如何获得一段好记、易拼写、有意义的域名,是很多人都面临的问题。本文将介绍域名抢注和域名注册的相关内容,并推荐ym.qqmu.com这个可靠的域名注册平台。 一、什么是域…...

【20】c++设计模式——>组合模式
组合模式定义 C组合模式(Composite Pattern)是一种结构型设计模式,他允许将对象组合成树形结构来表示“部分-整体”的层次结构;在组合模式中有两种基本类型的对象:叶子对象和组合对象,叶子对象时没有子对象…...

Jetpack:004-如何使用文本组件
文章目录 1. 概念介绍2. 使用方法2.1 通用参数2.2 专用参数 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack组件在布局中的对齐方式,本章回中主要介绍文 本组件的使用方法。闲话休提,让我们一起Talk Android Jetpack吧 1. 概念介绍 我们在本章…...

JVM(八股文)
目录 一、JVM简介 二、JVM中的内存区域划分 三、JVM加载 1.类加载 1.1 加载 1.2 验证 1.3 准备 1.4 解析 1.5 初始 1.6 总结 2.双亲委派模型 四、JVM 垃圾回收(GC) 1.确认垃圾 1.1 引用计数 1.2 可达性分析(Java 采用的方案&a…...
C#WPF标记扩展应用实例
本文介绍C#WPF标记扩展应用实例 一、标记扩展 标记扩展是一个 XAML 语言概念。 用于提供特性语法的值时,大括号({ 和 })表示标记扩展用法。 此用法指示 XAML 处理不要像通常那样将特性值视为文本字符串或者可转换为字符串的值。就是类似于值用变量的意思。 WPF 应用编程中…...

四维曲面如何画?matlab
clc; clear all [theta,phi]meshgrid(linspace(0,pi,50),linspace(0,2*pi,50)); zcos(theta); xsin(theta).*cos(phi); ysin(theta).*sin(phi); f-1*((x.*y).2(y.*z).2(z.*x).^2); surf(sin(theta).*cos(phi).*f,sin(theta).*sin(phi).*f,cos(theta).*f,f) 结果...

软件培训测试高级工程师多测师肖sir__html之作业11
html之作业 案例1: 截图: 代码: <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表单</title></head><body><table style"background-color:red" bo…...

详解一典型的反激式开关电源方案
理解一个单端反激式开关电源方案: 1、抛出问题: 如图,在某系统方案上看到下图所示的单端反激式开关电源方案。 2、解析问题: 2.1、乍一看: 典型的AC-DC电路,考虑了安规及过压过流保护,如&am…...
AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型)
AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型) 基带处理(Baseband Processing)是一种信号处理技术,用于在通信系统中处理和调制基带信号。基带信号是指未经过调制的信号,通常包含原始数…...

阿里云上了新闻联播
我是卢松松,点点上面的头像,欢迎关注我哦! 阿里新任的CEO吴泳铭上央视新闻联播了! 在昨天的新闻联播里,出席科技座谈会,有一个特别镜头,出现了阿里新任CEO吴泳铭的镜头。 这个信号意义明显,我…...
算法练习12——跳跃游戏
LeetCode 55 跳跃游戏 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 贪…...
Java架构师系统架构设计服务拆分
目录 1 服务拆分和子系统模块拆分1.1 服务化架构的优势2 描绘系统蓝图里面的详解服务2.1 为什么拆分服务3 服务拆分的基本要求3.1 服务功能是自包含的3.2 服务呢应该具备独立性和专业性3.3 服务是无状态的3.4 服务之间采用轻量级的通讯机制4 服务拆分的基本方法4.1 按业务边界拆…...
通用任务批次程序模板
通用批次任务模板 我们总会遇到需要使用批次任务处理问题的场景,任务有很多不同类型的任务,同时这些任务可能都有大致相同,甚至抽象出来共同的执行阶段状态。 任务的执行肯定无法保证一帆风顺,总会在某个时间阶段被打断ÿ…...

Rust专属开发工具——RustRover发布
JetBrains最近推出的Rust集成开发工具——RustRover已经发布,官方网站:RustRover: Rust IDE by JetBrains JetBrains出品过很受欢迎的开发工具IntelliJ IDEA、PyCharm等。 RustRover优势 Rust集成环境,根据向导可自动下载安装rust开发环境提…...

数据结构:链表(1)
顺序表的优缺点 缺点: 1.插入数据必须移动其他数据,最坏情况下,就是插入到0位置。时间复杂度O(N) 2.删除数据必须移动其他数据,最坏情况下,就是删除0位置。时间复杂度O(N) 3.扩容之后,有可能会浪费空间…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...