TomCat环境下LoginServlet未触发问题排查求助
登录表单无法触发LoginServlet的问题排查与修复
问题概述
开发简单登录表单,要求用户输入邮箱和密码后点击登录按钮跳转至首页。使用TomCat服务器,login.jsp页面可正常加载,但点击登录按钮后LoginServlet完全未触发执行。
核心问题与修复方案
1. HTML表单未配置提交目标、请求方法及表单字段名
原login.jsp的表单存在三个关键问题:
- 未指定
action属性,默认提交到当前页面,不会发送请求到LoginServlet - 未指定
method="post",默认使用GET请求,而LoginServlet仅实现了doPost方法 - 输入框缺少
name属性,Servlet无法通过req.getParameter()获取用户输入值
修改后的login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html lang="en" > <head> <meta charset="UTF-8"> <title>Login</title> <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Rubik:400,700'> <link rel="stylesheet" href="styleLogin.css"> </head> <body> <div class="login-form"> <!-- 指定提交目标为LoginServlet的URL,使用POST方法 --> <form action="/login" method="post"> <h1>Login</h1> <div class="content"> <div class="input-field"> <label> <!-- 添加name属性,用于Servlet获取参数 --> <input type="email" name="email" placeholder="Email" autocomplete="nope"> </label> </div> <div class="input-field"> <label> <input type="password" name="password" placeholder="Password" autocomplete="new-password"> </label> </div> </div> <div class="action"> <!-- 明确指定按钮类型为submit,确保触发表单提交 --> <button type="submit">Sign in</button> </div> </form> </div> </body> </html>
2. web.xml与注解配置冲突
原代码同时使用了@WebServlet注解和web.xml的Servlet配置,且web.xml中添加了<jsp-file>/login.jsp</jsp-file>,导致访问/login时直接返回JSP页面,而非触发LoginServlet逻辑。
修复方案二选一:
方案A:保留@WebServlet注解,删除web.xml中的Servlet配置
修改后的web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0"> <!-- 移除LoginServlet的<servlet>和<servlet-mapping>配置,依赖@WebServlet注解完成映射 --> </web-app>
方案B:删除@WebServlet注解,修正web.xml配置
修改后的LoginServlet(移除注解):
package com.example.userbook.servlet; import com.example.userbook.manager.UserManager; import com.example.userbook.model.User; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class LoginServlet extends HttpServlet { UserManager userManager = new UserManager(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("DoPost triggered"); String email = req.getParameter("email"); String password = req.getParameter("password"); User user = userManager.getUserByEmailAndPassword(email, password); if (user == null) { // 直接转发到login.jsp,避免循环调用Servlet req.getRequestDispatcher("/login.jsp").forward(req, resp); } else { req.getRequestDispatcher("/").forward(req, resp); } } // 添加doGet方法,处理直接访问/login的请求,返回登录页 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getRequestDispatcher("/login.jsp").forward(req, resp); } }
修改后的web.xml(移除<jsp-file>标签):
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0"> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.example.userbook.servlet.LoginServlet</servlet-class> <!-- 移除<jsp-file>,确保请求触发Servlet逻辑 --> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>
3. 补充说明
原LoginServlet中若用户验证失败时转发到/login,会导致循环请求(因为/login映射到Servlet),需改为直接转发到login.jsp,避免无限循环。
内容的提问来源于stack exchange,提问作者Jack Cumber
相关产品推荐
相关产品推荐

