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

目录:

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

一. 问题引入

近在写一个 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 注解。

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

竞赛选题 python的搜索引擎系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python的搜索引擎系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;5分创新点&#xff1a;3分 该项目较为新颖&#xff…

如何用CSS样式实现一个优雅的渐变效果?

CSS渐变效果 CSS渐变&#xff08;Gradients&#xff09;是一种让两种或多种颜色平滑过渡的视觉效果&#xff0c;广泛应用于网页背景、按钮、边框等&#xff0c;以创造丰富的视觉体验。CSS提供了线性渐变&#xff08;Linear Gradients&#xff09;和径向渐变&#xff08;Radial…

【软件实施】软件实施概论

目录 软件实施概述定义主要工作软件项目的实施工作区别于一般的项目&#xff08;如&#xff1a;房地产工程项目&#xff09;软件实施的重要性挑战与对策软件项目实施的流程软件项目实施的周期 软件企业软件企业分类产品型软件企业业务特点产品型软件企业的分类产品型软件企业的…

web安全渗透测试十大常规项(一):web渗透测试之深入JAVA反序列化

渗透测试之PHP反序列化 1. Java反序列化1.1 FastJson反序列化链知识点1.2 FastJson反序列化链分析1.3.1 FastJson 1.2.24 利用链分析1.3.2 FastJson 1.2.25-1.2.47 CC链分析1.3.2.1、开启autoTypeSupport:1.2.25-1.2.411. Java反序列化 1.1 FastJson反序列化链知识点 1、为什…

【scau大数据原理】期末复习——堂测题

一、集群安装知识 启动集群的命令start-all.sh位于 Hadoop安装目录的sbin文件夹 目录下。 bin文件夹下包含常见的Hadoop,yarn命令&#xff1b;sbin命令下包含集群的启动、停止命令。 启动集群的命令start-all.sh包含 同时启动start-dfs.sh和start-yarn.sh 功能。…

JetBrains PyCharm 2024 mac/win版编程艺术,智慧新篇

JetBrains PyCharm 2024是一款功能强大的Python集成开发环境(IDE)&#xff0c;专为提升开发者的编程效率和体验而设计。这款IDE不仅继承了前代版本的优秀特性&#xff0c;还在多个方面进行了创新和改进&#xff0c;为Python开发者带来了全新的工作体验。 JetBrains PyCharm 20…

LED封装技术中SMD、COB和GOB的优缺点

在小间距LED显示屏的封装技术中&#xff0c;SMD、COB和GOB各有其优缺点&#xff0c;以下是对这些技术的详细分析&#xff1a; SMD&#xff08;Surface Mounted Devices&#xff09;表贴工艺技术 SMD技术是将LED灯珠焊接在电路板上的一种成熟技术&#xff0c;广泛应用于LED显示屏…

java+mysql通讯录管理

完整代码地址如果控制台打印出现乱码&#xff0c;进行如下设置

10分钟完成微信JSAPI支付对接过程-JAVA后端接口

引入架包 <dependency><groupId>com.github.javen205</groupId><artifactId>IJPay-WxPay</artifactId><version>${ijapy.version}</version></dependency>配置类 package com.joolun.web.config;import org.springframework.b…

DC-DC原理,升降压原理,BUCK,BOOST

DC-DC简述 开关电源包括电源模块&#xff0c;可以直接使用&#xff0c;不需要外部电路&#xff0c;提供的功率比较小。还有电源稳压器&#xff0c;这种功率MOS一般集成在芯片内部&#xff0c;但是需要选择外部电感。另外还有PWM控制器&#xff0c;需要选择功率MOS&#xff0c;二…

centos上部署Ollama平台,实现语言大模型本地部署

网上有很多大模型&#xff0c;很多都是远程在线调用ChatGPT的api来实现的&#xff0c;自己本地是没有大模型的&#xff0c;这里和大家分享一个大模型平台&#xff0c;可以实现本地快速部署大模型。 Ollama是一个开源项目&#xff0c;它提供了一个平台和工具集&#xff0c;用于部…

【Python】已解决:ModuleNotFoundError: No module named ‘LAC‘

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘LAC‘ 一、分析问题背景 在开发或运行Python程序时&#xff0c;可能会遇到各种各样的报错&#xff0c;其中“ModuleNo…

stm32-hal库(5)--usart串口通信三种模式(主从通信)(关于通信失败和串口不断发送数据问题的解决)

问题&#xff1a; 最近发现&#xff0c;stm32cubemx最新版本f1系列的hal库&#xff08;1.85版本&#xff09;生成的hal库&#xff0c;其中stm32f1xx_hal_uart.c的库文件中&#xff0c;其串口发送接收存在一些问题&#xff1a; 1.没有使用 __HAL_LOCK 和 __HAL_UNLOCK 宏&…

多元时间序列分析——VAR(向量自回归模型)

VAR模型主要是考察多个变量之间的动态互动关系&#xff0c;从而解释各种经济冲击对经济变量形成的动态影响。这种动态关系可通过格兰杰因果关系、脉冲响应以及方差分解来进一步明确和可视化。VAR模型主要研究内生变量之间的关系&#xff0c;内生变量就是参与模型并由模型体系内…

【数据结构】(C语言):链表

链表&#xff1a; 基本单位是节点。节点至少两部分&#xff1a;数据&#xff0c;下一个数据的地址。头指针head&#xff0c;始终指向链表的第一个节点。若没有节点&#xff0c;则headNULL。链表在内存中是非连续的。不能使用索引&#xff08;下标&#xff09;查找元素。只能从…

【Vue】Vue3基础

VUE3基础 1、简介2、创建工程2.1 基于vue-cli创建&#xff08;脚手架webpack&#xff09;2.2 基于vite创建&#xff08;推荐&#xff09;2.3 目录结构2.4 vscode插件推荐 3、核心语法3.1 选项式&#xff08;options API&#xff09;和组合式&#xff08;composition API&#x…

of_match_device是怎么匹配的

这里以spi-gpio.c为例 先判断有没有匹配表和dev中有没设备树节点 struct device中有个保存设备树节点的结构体 可通过三种方式匹配&#xff1a;名字、类型、compatible 匹配成功&#xff0c;则执行第一个

海外媒体发稿:媒体宣发套餐的作用分享-华媒舍

一、神奇媒体宣发套餐 神奇媒体宣发套餐是一项专业的多媒体宣传推广服务&#xff0c;旨在帮助企业、个人快速提升品牌知名度和曝光度。它通过全面覆盖主流媒体、社交网络以及各大网络平台&#xff0c;将您的宣传信息传递给广泛的受众群体&#xff0c;实现全方位、多角度的宣传…

无人机无刷电机理论教学培训课程

本文档为一份关于Brushless电机理论的详细教程&#xff0c;由TYTO Robotics编制&#xff0c;旨在帮助用户理解brushless电机的工作原理、特性以及如何通过实验测定其关键参数Kv和Kt。文档首先介绍了brushless电机的基本组成&#xff0c;包括静止的定子和旋转的转子&#xff0c;…

python循环结构

1.while 循环 语句&#xff1a; while 循环条件表达式&#xff1a; 代码块 else&#xff1a; 代码块 小练&#xff1a; 设计一百以内的偶数相加 n 0 while n < 100:n 1if n % 2 0 :print(n) 判断是不是闰年&#xff08;四年一润和百年不润&#xff0c;或者四百年一润&am…