You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat Servlet中request.getParameter获取参数为空排查求助

问题描述

我在Tomcat服务器的Servlet中遇到异常问题:明明能够打印出请求中的参数,但执行user == null || user.isEmpty()判断时却返回true。请求帮忙排查该问题的原因。


Servlet类代码

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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;

@WebServlet("/Login")
@MultipartConfig
public class login extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private Connection conn = null;
    
    public void init() {
        ServletContext ctx = getServletContext();
        
        final String DB_URL = ctx.getInitParameter("dbUrl");
        final String USER = ctx.getInitParameter("dbUser");
        final String PASS = ctx.getInitParameter("dbPass");
        final String DRIVER = ctx.getInitParameter("dbDriver");
        
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
        
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String user = request.getParameter("username");
        String password = request.getParameter("password");
        
        if(user == null || password == null || user.isEmpty() || password.isEmpty()) response.getWriter().write("missing fields");
    }
    
    public void destroy() {
        try {
            conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

前端请求代码

请求触发逻辑

document.getElementById("loginbutton").addEventListener("click", (e)=>{
    const formd = document.getElementById("login_form");
    
    makeCall("POST", "Login", formd, (request) => {
        if(request.readyState == 4 && request.status == 200){
            console.log("Cioa");
        }
    }, null, false);
});

请求工具函数

function makeCall(method, url, formElement, callBack , objectToSend , reset = true) {
    let request = new XMLHttpRequest();
    request.onreadystatechange = function() {
        callBack(request);
    };

    request.open(method, url);

    if (formElement == null && objectToSend == null) {
        request.send();
    } else if(formElement != null){
        //Send the form
        request.send(new FormData(formElement));
    } else {
        //Send the object
        let toSend = JSON.stringify(objectToSend);
        request.send(toSend);
    }

    //If there is a form and reset is true -> reset the fields of the form
    if (formElement !== null && reset === true) {
        formElement.reset();
    }
}

问题排查与解决方案

核心原因

你给Servlet添加了@MultipartConfig注解,这会强制Servlet将所有请求按multipart/form-data类型解析。但前端通过FormData发送无文件的表单时,部分浏览器会自动将请求的Content-Type设为application/x-www-form-urlencoded,而非multipart/form-data。这种类型不匹配的情况下,request.getParameter()无法正确读取参数,导致获取到的user/password为null或空字符串。

另外,即便前端发送的是multipart/form-data请求,标记了@MultipartConfig的Servlet也不能用request.getParameter()读取参数,必须通过request.getPart()方法获取。


解决方案

方案一:移除@MultipartConfig注解(推荐,若无需文件上传)

如果你的登录表单不需要支持文件上传,直接删除Servlet类上的@MultipartConfig注解即可。此时Servlet会默认解析application/x-www-form-urlencoded类型的请求,request.getParameter()能正常获取参数。

修改后的Servlet头部:

@WebServlet("/Login")
// 移除@MultipartConfig注解
public class login extends HttpServlet {
    // 剩余代码保持不变
}

方案二:保留注解并改用getPart()解析参数(若需支持文件上传)

如果后续需要添加文件上传功能,保留@MultipartConfig,同时修改参数读取逻辑:

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String user = getParamFromPart(request, "username");
    String password = getParamFromPart(request, "password");
    
    if(user == null || password == null || user.isEmpty() || password.isEmpty()) {
        response.getWriter().write("missing fields");
    }
}

// 新增工具方法,从Part中读取参数值
private String getParamFromPart(HttpServletRequest request, String paramName) throws IOException, ServletException {
    Part part = request.getPart(paramName);
    if (part == null) {
        return null;
    }
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream()))) {
        return reader.readLine();
    }
}

调试验证步骤

可以添加以下代码辅助定位问题:

  1. 打印请求的Content-Type,确认类型是否匹配:
    System.out.println("Request Content-Type: " + request.getContentType());
    
  2. 打印参数的实际值和长度,排查是否存在空白字符:
    String user = request.getParameter("username");
    System.out.println("user value: '" + user + "', length: " + (user != null ? user.length() : 0));
    

内容的提问来源于stack exchange,提问作者Proth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:40:26