最近写javaweb出现的一个小bug---前端利用 form 表单传多项数据,后端 Servlet 取出的各项数据均为空

news2024/11/26 7:50:56

目录:

  • 一. 问题引入
  • 二 解决问题

一. 问题引入

近在写一个 java web 项目时,遇到一个让我头疼了晚上的问题:前端通过 post 提交的 form 表单数据可以传到后端,但当我从 Servlet 中通过 request.getParameter(“name”) 拿取各项数据时,得到的内容均为 Null !

为便于读者理解,我先描述下当前的业务场景:弹窗界面用于提示录入合同名称,合同类型和合同文件(这些信息将被组织在一个 form 表单中)。在点击 “归档合同” 后,该 form 表单会提交全部数据至后台,并将这些数据存放至数据库中。
在这里插入图片描述
下面是这部分内容对应的代码

前端代码(仅展示 form 表单和对应的 JS 代码):


                        <!-- Contract archiving form -->
                        <form id="contractArchivingForm" class="bg-light p-3" action="file.do" method="post" enctype="multipart/form-data" >
                            <input type="hidden" name="flag" value="insert"/>
                            <div class="form-group">
                                <label for="contractName">合同名称</label>
                                <input type="text" class="form-control" id="contractName"  name="contractName" placeholder="输入合同名称" required>
                            </div>
                            <div class="form-group">
                                <label for="contractCategory">合同类别</label>
                                <select class="form-control" id="contractCategory" name="contractCategory">
                                    <option>租赁协议</option>
                                    <option>销售合同</option>
                                    <option>服务协议</option>
                                    <!-- More contract categories can be added as needed -->
                                </select>
                            </div>
                            <div class="form-group">
                                <label for="contractFileUpload">上传合同文件</label>
                                <input type="file" class="form-control-file" id="contractFileUpload" name="contractFileUpload" required>
                                <small class="form-text text-muted">请上传PDF格式的文件,大小不超过10MB。</small>
                            </div>
                            <div class="form-group form-check">
                                <input type="checkbox" class="form-check-input" id="agreement">
                                <label class="form-check-label" for="agreement">我确认合同信息准确无误,并同意归档。</label>
                            </div>
                            <input type="submit" class="btn btn-primary" value="归档合同" >
                        </form>

后端代码

package com.jjy.web.servlet;

import com.jjy.pojo.FileInfo;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@WebServlet("/file.do")
public class FileInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String flag = req.getParameter("flag");
        System.out.println("未进入"+flag);
        if ("insert".equals(flag)) {
            System.out.println(flag);
            insertFileinfo(req, resp);
        }
    }

    private void insertFileinfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String contractName = request.getParameter("contractName");
        String contractCategory = request.getParameter("contractCategory");
        FileInfo fileInfo = new FileInfo();

        Part part = request.getPart("contractFileUpload");
        //通过Part对象得到上传的文件名
        String fileName = part.getSubmittedFileName();
        System.out.println("上传文件名:" + fileName);
        //得到文件存放的路径
        String filePath = request.getServletContext().getRealPath("/");
        System.out.println("文件存放路径:" + filePath);
        part.write(filePath + "/" + fileName);
        fileInfo.setFilename(contractName);
        fileInfo.setFiletype(contractCategory);
        LocalDateTime currentDateTime = LocalDateTime.now();

        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 将LocalDateTime转换为String
        String formattedDateTime = currentDateTime.format(formatter);
        fileInfo.setFiletime(formattedDateTime);
        System.out.println(fileInfo);
        // 处理完毕后重定向或者显示成功消息
        response.sendRedirect("guidang.html");

    }
}

以上代码的逻辑很清晰:
1、前端获取输入;
2、后端拿取输入,并完成添加。

但在运行时,后端 Servlet 取出的值始终为 null:
当我用 F12 在浏览器中查看包的信息时,发现 post 请求中的确含数据!!!
在这里插入图片描述

二 解决问题

这时候通过网上查询,基本可以得到以下排错手段

1、form 表单中未写 name 属性;
2、jsp 的提交方式与 servlet 不一致(如:在 jsp 中用的 post ,但是在对应 servlet 中写的是 doGet);
3、form 表单的 enctype 属性与 servlet 不一致;
4、servlet 中的 getParameter() 参数与 form 表单不一致。

但遗憾的是,我都正确配置了这些参数,可取出的就是 null 。

最后发现

在前端用了 multipart/form-data 封装 form 表单数据,后端接受到的数据是一个含文本、二进制数据的复杂数据对象,这时候肯定不能直接通过 getParameter() 获取。因为 getParameter() 方法是不能对这种 “打包数据对象” 进行解析的。这时候最简单的解决办法就是在 servlet 处添加 @MultipartConfig 注解,以告知 servlet,此时接受到的数据是同时含文本、二进制数据的,需要在 getParameter() 前进行适当预处理。这样一来, getParameter() 才能从前端发来的数据对象中正确解析出各项 name 对应的值。

所以,正确的后端代码应改为:

package com.jjy.web.servlet;

import com.jjy.pojo.FileInfo;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@MultipartConfig
@WebServlet("/file.do")
public class FileInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String flag = req.getParameter("flag");
        System.out.println("未进入"+flag);
        if ("insert".equals(flag)) {
            System.out.println(flag);
            insertFileinfo(req, resp);
        }
    }

    private void insertFileinfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String contractName = request.getParameter("contractName");
        String contractCategory = request.getParameter("contractCategory");
        FileInfo fileInfo = new FileInfo();

        Part part = request.getPart("contractFileUpload");
        //通过Part对象得到上传的文件名
        String fileName = part.getSubmittedFileName();
        System.out.println("上传文件名:" + fileName);
        //得到文件存放的路径
        String filePath = request.getServletContext().getRealPath("/");
        System.out.println("文件存放路径:" + filePath);
        part.write(filePath + "/" + fileName);
        fileInfo.setFilename(contractName);
        fileInfo.setFiletype(contractCategory);
        LocalDateTime currentDateTime = LocalDateTime.now();

        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 将LocalDateTime转换为String
        String formattedDateTime = currentDateTime.format(formatter);
        fileInfo.setFiletime(formattedDateTime);
        System.out.println(fileInfo);
        // 处理完毕后重定向或者显示成功消息
        response.sendRedirect("guidang.html");

    }
}

即:添加 @MultipartConfig 注解。

这时,所有的数据均能正确地取出!

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力
在这里插入图片描述

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

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

相关文章

正版软件 | R-Studio Corporate:企业级数据恢复的终极解决方案

数据是企业的生命线&#xff0c;而数据丢失可能随时威胁到企业的正常运营。R-Studio Corporate 是一款专为企业环境设计的多功能数据恢复软件&#xff0c;确保您在面临数据危机时&#xff0c;能够迅速、高效地恢复宝贵数据。 跨平台操作&#xff0c;灵活恢复 R-Studio Corporat…

小时候的子弹击中了现在的我-hive进阶:案例解析(第18天)

系列文章目录 一、Hive表操作 二、数据导入和导出 三、分区表 四、官方文档&#xff08;了解&#xff09; 五、分桶表&#xff08;熟悉&#xff09; 六、复杂类型&#xff08;熟悉&#xff09; 七、Hive乱码解决&#xff08;操作。可以不做&#xff0c;不影响&#xff09; 八、…

收银系统源码-千呼新零售2.0【线上营销】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看&a…

WINDOWS+PHP+Mysql+Apache环境中部署SQLi-Labs、XSS-Labs、UPload-Labs、DVWA、pikachu等靶场环境

web渗透测试学习&#xff0c;需要自己搭建一些靶场&#xff0c;本人主要介绍在WINDOWSPHPMysqlApache环境中部署SQLi-Labs、XSS-Labs、UPload-Labs、DVWA、pikachu等靶场环境。以下是靶场代码下载的链接&#xff1a; pikachu靶场代码 链接&#xff1a;https://pan.baidu.com/s…

GEO数据挖掘-富集分析、TinyArray简化流程、多组样本分析more

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 富集分析一些理论知识具体代码 富集不到的补救措施更多资料---问题数据和常见错误分析Part4-复杂数据及其分析多分组数据分析流程 tinyarray简化版本分析流程多分组…

Interview preparation--Elasticsearch写入原理与调优

ES的写入过程 ES支持的写操作 create&#xff1a; create操作不同于put操作&#xff0c;put操作的时候如果当前put的数据存在则会被覆盖&#xff0c;如果put操作的时候加上操作类型create&#xff0c;如果数据存在则会返回失败&#xff0c;比如&#xff1a;PUT /pruduct/_cre…

实测2024年最佳的三款Socks5代理IP网站

一、引言 在浩瀚的网络世界中&#xff0c;Socks5代理IP服务如同导航灯塔&#xff0c;指引我们穿越数据海洋&#xff0c;安全、稳定地访问目标网站。作为专业的测评团队&#xff0c;我们深知一款优秀的Socks5代理IP网站需要具备哪些特质&#xff1a;稳定的IP资源、高效的连接速…

QT基本对话框(基本对话框、工具盒类、进度条、调色板与电子钟、可扩展对话框、程序启动画面)

此篇文章通过实例介绍基本对话框的用法。首先介绍标准文件对话框&#xff08;QFileDialog&#xff09;、标准颜色对话框&#xff08;QColorDialog&#xff09;、标准字体对话框&#xff08;QFontDialog&#xff09;、标准输入对话框&#xff08;QInputDialog&#xff09;以及标…

AI绘画 Stable Diffusion【特效文字】:火焰特效艺术字,轻松搞定特效生成!

大家好&#xff0c;我是画画的小强 今天我们继续艺术字系列的分享&#xff0c;艺术字的玩法很多&#xff0c;今天给大家带来的是火焰特效艺术字的制作。我们先来看火焰特效艺术字的效果图。 一. 火焰特效文字的制作方法 【第一步】&#xff1a;制作底图 这里制作底图使用白底…

VMware Workstation 安装 Centos 虚拟机

1. 下载 VMware Workstation 直接上网找官网下载即可 2. 下载 Centos 镜像 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 3.打开 VMware 创建虚拟机 3.1点击创建虚拟机 3.2 选择自定义安装 3.3 选择使用 Workstation 的版本 版本越高兼容性越低但性能越好&#xff0c;一…

2024年Stable Diffusion应用入门,AI绘画超详细兼职攻略,从零开始!

. AI绘画&#xff1a; 利用AI工具在AI绘画上的应用非常广泛&#xff0c;涵盖了从艺术创作到工业设计等多个领域。 目前市面上有许多AI绘画软件和工具&#xff0c;适合不同需求的用户。 例如&#xff0c;Midjourney、DALL-E 2、Stable Diffusion、DreamStudio等都是较为知名的…

深入了解Qt 控件:Display Widgets部件(1) 以及 QT自定义控件(电池)

QT自定义控件(电池&#xff09; 在线调色板Qt之CSS专栏Chapter1 QT自定义控件(电池&#xff09;Chapter2 Qt教程 — 3.5 深入了解Qt 控件&#xff1a;Display Widgets部件(1)1 Display Widgets简介2 如何使用Display Widgets部件 Chapter3 Qt自定义控件电池组件使用前言一、最基…

AIGC实战:LLaMA2打造中文写作利器——数据准备与模型训练全攻略

目录 一、下载并加载中文数据集二、中文数据集处理 1、数据格式 2、数据集处理之tokenizer训练格式 1&#xff09;先将一篇篇文本拼凑到一起&#xff08;只是简单的拼凑一起&#xff0c;用于训练tokenizer&#xff09; 2&#xff09;将数据集进行合并 3、数据集处理之模型&am…

新书速览|解密AI绘画与修图: Stable Diffusion+Photoshop

《解密AI绘画与修图&#xff1a; Stable DiffusionPhotoshop》 本书内容 《解密AI绘画与修图&#xff1a;Stable DiffusionPhotoshop》全面介绍了Photoshop和Stable Diffusion的交互方式&#xff0c;以及各自的AI功能和具体使用方法。除了讲解功能&#xff0c;还通过实际案例加…

浪潮信息存储的灵魂:平台化+场景化 全面释放数据价值

在数字化浪潮的席卷下&#xff0c;浪潮信息存储平台凭借卓越的性能和稳定性&#xff0c;正日益成为企业释放数据价值的重要力量。近日&#xff0c;浪潮信息出席了“2024数据基础设施技术峰会”&#xff0c;相关代表聚焦当前数据价值的释放话题&#xff0c;围绕先进存储基础设施…

Mongodb安装与配置

Mongodb的下载 这里下载的是MongoDB 7.0.11版本的 首先进入官网&#xff1a;https://www.mongodb.com/ 点击完上面两步后&#xff0c;加载来到该页面&#xff0c;选择自己的版本、系统&#xff0c;是压缩包(zip)还是安装包(msi)。 下载好之后能&#xff0c;来到安装包哪里&a…

爱奇艺 Opal 机器学习平台:特征中心建设实践

01 综述 Opal 是爱奇艺大数据团队研发的一站式机器学习平台&#xff0c;旨在提升特征迭代、模型训练效率&#xff0c;帮助业务提高收益。整个平台覆盖了机器学习生命周期中特征生产、样本构建、模型探索、模型训练、模型部署等在内的多个关键环节。其中特征作为模型训练的基石…

maven安装jar和pom到本地仓库

举例子我们要将 elastic-job-spring-boot-starter安装到本地的maven仓库&#xff0c;如下&#xff1a; <dependency><groupId>com.github.yinjihuan</groupId><artifactId>elastic-job-spring-boot-starter</artifactId><version>1.0.5&l…

基于SpringBoot网吧管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; Java精品实战案例《600套》 2025-2026年最值得选择的Java毕业设计选题大全&#xff1…

TCP/IP模型原理(理论)

TCP/IP模型 1. 网络模型简介2. 应用层2.1 URL2.1.1 urlencode和urldecode 2.2 HTTP协议2.2.1 HTTP协议格式2.2.2 HTTP问题2.2.3 HTTPS 3 传输层3.1 端口号3.2 udp3.2.1 udp协议帧格式3.2.2 udp特点3.2.3 udp缓冲区3.2.4 注意 3.3 tcp协议3.3.1 tcp协议段格式3.3.2 确认应答机制…