@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()方法读取文本字段的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/101149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ - 智能指针 - auto_ptr - unique_ptr - std::shared_ptr - weak_ptr

前言 C当中的内存管理机制需要我们自己来进行控制&#xff0c;比如 在堆上 new 了一块空间&#xff0c;那么当这块空间不需要再使用的时候。我们需要手动 delete 掉这块空间&#xff0c;我们不可能每一次都会记得&#xff0c;而且在很大的项目程序当中&#xff0c;造成内存泄漏…

milvus测试

milvus测试 目标 其实&#xff0c;我应该弄明白他的输入输出分别是什么&#xff1f; 输入是图片&#xff0c;图片经过ml模型进行特征提取&#xff0c;再在milvus中进行存储或者检索 部署 ✘ delldell-Precision-3630-Tower  /nvme/baum/git-project/milvus   master …

js中await用法

在JavaScript中&#xff0c;await用于暂停异步函数执行&#xff0c;等待Promise对象的解决。当Promise对象解决时&#xff0c;await将返回被解决的值&#xff0c;否则它将抛出一个被拒绝的Promise错误。 下面是一些使用await的例子&#xff1a; 使用await等待一个Promise对象…

机器学习极值问题

给出二次函数 f ( x ) 1 2 x T P x q T x r f(x) \frac{1}{2}x^TPx q^Tx r f(x)21​xTPxqTxr的极小值点。(P是对称矩阵) 解&#xff1a; 对f(x)求导数&#xff1a; f ( x Δ x ) − f ( x ) 1 / 2 ( x Δ x ) T P ( x Δ x ) q T ( x Δ x ) r − 1 / 2 x T P x…

TIME-LLM: TIME SERIES FORECASTING BY REPROGRAMMING LARGE LANGUAGE MODELS

本文是LLM系列文章&#xff0c;针对《TIME-LLM: TIME SERIES FORECASTING BY REPROGRAMMING LARGE LANGUAGE MODELS》的翻译。 time-llm:通过重新编程大型语言模型来预测时间序列 摘要1 引言2 相关工作3 方法4 主要结果5 结论和未来工作 摘要 时间序列预测在许多现实世界的动…

优化 if-else 语句的最佳方案

文章目录 前言一、条件表达式优化1、先行计算条件表达式 二、条件判断结构优化1、使用三目运算符2、省略最后的 else3、减少 if 语句包裹的内容4、异常状态先行返回5、条件匹配案例 三、使用 Optional 类1、对象判空 - 对象为空&#xff0c;则抛出异常2、对象判空 - 对象非空&a…

SpringBoot 如何使用 Ehcache 作为缓存

使用Spring Boot Sleuth进行分布式跟踪 在现代分布式应用程序中&#xff0c;跟踪请求和了解应用程序的性能是至关重要的。Spring Boot Sleuth是一个分布式跟踪解决方案&#xff0c;它可以帮助您在分布式系统中跟踪请求并分析性能问题。本文将介绍如何在Spring Boot应用程序中使…

选择适合变更管理的产品开发工具的要点和建议

什么是变更管理&#xff1f; 变更管理是指导组织改进的学科。由于可观察到的行为变化&#xff0c;它会导致永久性变化。它确保您的组织以彻底、有序和可持续的方式学习和改进。成功的改进项目需要个人和团队保持一致&#xff0c;他们有共同的愿景&#xff0c;他们知道如何定义…

指数移动平均EMA

指数移动平均EMA 介绍示例代码 补充&#xff1a;torch.lerp 介绍 指数移动平均&#xff08;Exponential Moving Average&#xff0c;简称 EMA&#xff09;是一种常用的平滑方法&#xff0c;通常用于时间序列数据的平滑处理。EMA 可以减小噪声的影响&#xff0c;使得数据更加平…

收录一些常见的算法题型

常用算法 字符串 s.trim():去掉字符串首尾的空格s.split("\\s"):按照空格对字符串分割 树 前中后序遍历 /*** 统一一下* param root* return*///前序public static List<Integer> preOrder(TreeNode root){List<Integer> list new ArrayList();Stac…

MidJourney | AI绘画也有艺术

免费绘画&#xff0c;体验更多AI可关&注公&众&号&#xff1a;AI研究工厂

大数据学习(2)Hadoop-分布式资源计算hive(1)

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博>主哦&#x…

【.net core】yisha框架 SQL SERVER数据库 反向递归查询部门(子查父)

业务service.cs中ListFilter方法中内容 //反向递归查询部门列表List<DepartmentEntity> departmentList await departmentService.GetReverseRecurrenceList(new DepartmentListParam() { Ids operatorInfo.DepartmentId.ToString() });if (departmentList ! null &am…

如何将gif变成视频?3个转换方法

如何将gif变成视频&#xff1f;没错&#xff0c;GIF是一种动态图片格式&#xff0c;与视频在本质上有所区别。在一些自媒体平台上&#xff0c;我们无法直接分享GIF格式的图片&#xff0c;但可以将其转换为视频格式后再进行分享。因此&#xff0c;当我们想要分享我们喜欢的GIF图…

香港硬防服务器的防御有什么优缺点?

​  在选择服务器时&#xff0c;安全性是一个重要的考虑因素。而对于那些需要高级防御功能的用户来说&#xff0c;香港硬防服务器可能是一个不错的选择。它也有一些优缺点需要考虑。 香港硬防服务器优点&#xff1a; 强大的硬件资源&#xff1a;香港硬防服务器拥有足够的硬件…

nginx如何安装 以及nginx的配置文件

Nginx 网站服务 是一个高性能 轻量级web服务软件&#xff0c; 高新能&#xff1a;对http并发连接的处理能很高&#xff0c;单台处理器可支持30000-50000个并发请求&#xff0c;&#xff08;一般设置在20000个左右&#xff09; 轻量级&#xff1a;nginx软件很小&#xff0c;安装…

ChromeDriver驱动最新版下载

下载地址ChromeDriver - WebDriver for Chrome - Downloads selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 113 Current browser version is 117.0.5938.150 with binar…

vim基础指令(自用)

这个是自己随便写的&#xff0c;类似于笔记 vim 多模式编辑器 查看指令&#xff1a; gg&#xff1a; 定位光标到最开始行 shift(按)g 定位到最结尾行 nshift(按)g 定位到任意行 shift&#xff04; 定位到本行结尾 0 定位到本行开头 w&#xff1a;跨单词移动 h.j.k,l: 左下上右 …

Python 快速排序

快速排序使用分治法&#xff08;Divide and conquer&#xff09;策略来把一个序列&#xff08;list&#xff09;分为较小和较大的2个子序列&#xff0c;然后递归地排序两个子序列。 步骤为&#xff1a; 挑选基准值&#xff1a;从数列中挑出一个元素&#xff0c;称为"基准&…

【RuoYi-Cloud项目研究】【ruoyi-gateway模块】Spring Gatewaye和Sentinel实现网关流控

文章目录 1. RuoYi 实现了对服务的限流2. 网关与普通服务的限流区别2.1. 引入的组件有差别2.2. 配置文件有差别 3. 注意事项 备注&#xff1a; 1、RuoYi 网关默认只在 nacos 配置中心的 Sentinel 限流配置中配置了对“服务限流”&#xff0c;而没有详细控制到限流的 URL。 2、各…