@MultipartConfig注解

news2024/11/16 0:56:31

前言:

        在学习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<>();

    @Override
    protected 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.coloradmin.cn/o/1078571.html

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

相关文章

一种超轻量级神经网络加速器实现

一 目标 针对资源受限&#xff0c;SWaP敏感的边缘计算应用场景&#xff0c;探索稳健而高效的计算架构&#xff0c;算法和应用。 并完成超轻量级神经网络加速器设计和验证。 1、实时性能&#xff1a;30~50FPS 2、超低功耗&#xff1a;mW级别 3、资源受限&#xff1a;包括…

学习记忆——数学篇——案例——代数——方程——一元二次方程

重点记忆法 a x 2 b x c 0 ax^2bxc0 ax2bxc0 整体可以由&#xff1a; 根 ⟹ \Longrightarrow ⟹ △ △ △ ⟹ \Longrightarrow ⟹ 求根公式 x 1 , 2 x_{1,2} x1,2​ − b △ 2 a \frac{-b\sqrt{△}}{2a} 2a−b△ ​​ ⟹ \Longrightarrow ⟹ 韦达定理 ⟹ \Longrightarr…

Acwing.4742 电(动态规划)

题目 某城市有 N 个电力节点&#xff0c;编号 1∼N。 这些电力节点形成的电力网络&#xff0c;可以看作一个 N 个节点 N−1 条边的连通图。 每个电力节点都有一个固定的电容&#xff0c;其中第 i 个节点的电容为 Ai。 现在&#xff0c;可以选择其中一个节点进行供电&#x…

婚礼避坑指南(tips分享)

1️⃣自己买婚纱很可能比租的更省钱&#xff0c;更时髦。我是先去婚纱店看&#xff0c;玲琅满目的婚纱让我看花了眼&#xff0c;试穿了几件重工的婚纱感觉并不是自己喜欢的款式&#xff0c;穿着也不舒服&#xff0c;而且租金都要几千。自己在京东上400买的反倒特别满意。 2️…

apipost测试工具的基本使用

目录 什么是 API Post&#xff1f; 步骤1&#xff1a;下载 步骤2&#xff1a;登录 步骤3&#xff1a;新建目录 步骤4&#xff1a;新建接口 步骤5&#xff1a;参数 步骤6&#xff1a;参数的导入导出 一.先找一个有参数的接口进行测试 二.新建一个接口 步骤7&#xff1…

2023年【司钻(钻井)】考试报名及司钻(钻井)试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 司钻&#xff08;钻井&#xff09;考试报名考前必练&#xff01;安全生产模拟考试一点通每个月更新司钻&#xff08;钻井&#xff09;试题及解析题目及答案&#xff01;多做几遍&#xff0c;其实通过司钻&#xff08;…

活动预告|DeFi和zkLogin专题Workshop AMA

Sui流动性质押黑客松于10月初落下帷幕&#xff0c;但随着Sui网络TVL的不断增加&#xff0c;大家对Sui生态DeFi的讨论持续增加。据DeFiLlama统计&#xff0c;截止10月10日Sui网络TVL突破4000万USD&#xff0c;不断创历史新高&#xff01;zklogin于9月底正式上线&#xff0c;用户…

C++ - 包装器

包装器 在 C 当中可能会有各种各样的可调用类型&#xff0c;比如 函数指针&#xff0c;仿函数&#xff0c;lambda 等等&#xff0c;那么这么多的可调用类型&#xff0c;我们在使用的时候就会犯迷糊&#xff0c;那可不可以统一控制一下呢&#xff1f; function包装器&#xff…

FaceFusion:探索无限创意,创造独一无二的面孔融合艺术!

FaceFusion&#xff1a;探索无限创意&#xff0c;创造独一无二的面孔融合艺术&#xff01; 它使用先进的图像处理技术&#xff0c;允许用户将不同的面部特征融合在一起&#xff0c;创造有趣和令人印象深刻的效果。这个项目的潜在应用包括娱乐、虚拟化妆和艺术创作&#xff0c;…

GIS 算法原理记录总结二:距离、方位角、沿线上的点的扩展算法及其使用(一)

GIS 算法原理记录总结二&#xff1a;距离、方位角、沿线上的点的扩展算法及其使用&#xff08;一&#xff09; 在了解了距离算法、方位角算法之后&#xff0c;就可以根据距离、方位角进行一些扩展应用。这里罗列如下&#xff1a; 一、计算线段中点&#xff08;turf.midpoint&…

❋JQuery的快速入门2 jq动画与案例

目录 jq自定义动画【animate&#xff0c;stop】 案例1&#xff1a;大小图标 案例2&#xff1a;动态增加删除数据 案例3&#xff1a;动态留言与删除 案例4&#xff1a;动态进度条 案例5&#xff1a;点击三个相同的图片进行消除 jq自定义动画【animate&#xff0c;stop】 a…

艺术字画雕刻经营配送商城小程序的作用是什么

一副传神且精致的绘画/雕塑品不仅具有很好的观赏性&#xff0c;更具备售卖属性&#xff0c;当然由于产品本身本身的局限性&#xff0c;无论开店还是线上朋友圈推广&#xff0c;都难有效果。 通过【雨科】平台搭建字画雕刻经营商城&#xff0c;将所有产品线上售卖&#xff0c;电…

内网渗透面试问题

文章目录 1、熟悉哪些域渗透的手段2、详细说明哈希传递的攻击原理NTLM认证流程哈希传递 3、聊一下黄金票据和白银票据4、shiro反序列化漏洞的形成原因&#xff0c;尝试使用burp抓包查看返回包内容安装环境漏洞验证 5、log4j组件的命令执行漏洞是如何造成的6、画图描述Kerberos协…

vue 组件拖拽vue-slicksort应用

1.引入 import { SlickList, SlickItem, HandleDirective } from vue-slicksort 2.注册组件 components: {SlickList,SlickItem}, 3.应用<slick-listv-model"formData.goods"axis"xy":use-drag-handle"true"input"slickListSort"so…

vue3 添加水印效果

效果图 水印组件 <template><div class"elementdiv" ref"waterMarkRef"><slot></slot></div> </template><script setup> import { ref, onMounted, nextTick } from "vue"; import Watermark from …

Mock工具之Moco使用

一、什么是Mock mock英文单词有愚弄、嘲笑、模拟的意思&#xff0c;这里主要是模拟的意思 二、什么是Moco 开源的、基于java开发的一个mock框架支持http、https、socket等协议 三、Mock的特点 只需要简单的配置request、response等即可满足要求 支持在request 中设置headers、…

【Ceph Block Device】块设备挂载使用

文章目录 前言创建pool创建user创建image列出image检索image信息调整image大小增加image大小减少image大小 删除image从pool中删除image从pool中“延迟删除”image从pool中移除“延迟删除的image” 恢复image恢复指定pool中延迟删除的image恢复并重命名image 映射块设备格式化i…

Rockchip RK3399 - linux下抓取usb数据包

---------------------------------------------------------------------------------------------------------------------------- 开发板 &#xff1a;NanoPC-T4开发板eMMC &#xff1a;16GBLPDDR3 &#xff1a;4GB 显示屏 &#xff1a;15.6英寸HDMI接口显示屏u-boot &…

03黑马店评-添加商户缓存和商户类型的缓存到Redis

商户查询缓存 什么是缓存 实际开发过程中数据量可以达到几千万,缓存可以作为避震器防止过高的数据访问猛冲系统,避免系统内的操作线程无法及时处理信息而瘫痪 缓存(Cache)就是数据交换的缓冲区(储存临时数据的地方),我们俗称的"缓存"实际就是缓冲区内的数据(一般从…

L14D6内核模块编译方法

一、内核模块基础代码解析 一个内核模块代码错误仍然会导致的内核崩溃。 GPL协议&#xff1a;开源规定&#xff0c;使用内核一些函数需要 1、单内核的缺点 单内核扩展性差的缺点减小内核镜像文件体积&#xff0c;一定程度上节省内存资源提高开发效率不能彻底解决稳定性低的缺…