点击JSP按钮传递JSON参数时Servlet未执行问题求助
核心问题总结
点击Register按钮仅弹出JSON提示,AJAX请求未触发RegisterController执行,根源在于请求路径错误、JSON数据格式不匹配、Servlet接收数据方式错误、Servlet API版本与Tomcat不兼容这几个问题。
具体错误与修复步骤
1. AJAX请求路径错误
当前AJAX的url: '/register-controller'是根路径,会直接请求http://localhost:8080/register-controller,但你的项目上下文路径是test_register_war_exploded,正确的Servlet地址应该是http://localhost:8080/test_register_war_exploded/register-controller。
修复代码(index.jsp的AJAX部分):
$.ajax({ // 使用上下文路径拼接正确的Servlet地址 url: '${pageContext.request.contextPath}/register-controller', type: 'POST', data: JSON.stringify(data), dataType: 'json', contentType: 'application/json', mimeType: 'application/json', // 添加错误回调方便排查问题 error: function(xhr, status, error) { console.log("请求错误:", status, error); console.log("响应内容:", xhr.responseText); } });
2. AJAX数据格式不匹配
你设置了contentType: 'application/json',但直接传递JS数组data,jQuery会自动将其转换为表单格式(如firstname=xxx&lastname=xxx),与声明的JSON格式冲突,导致请求无法被Servlet正确解析。
修复代码(index.jsp的AJAX数据处理部分):
$("#register").click(function() { let data = []; let json = {}; $("input.add_register").each(function(){ json[this.name] = this.value; }); // 验证两次密码是否一致 if (json.password1 !== json.password2) { alert("两次输入的密码不一致!"); return; } // 整理密码字段,匹配后端User类的属性 json.password = json.password1; delete json.password1; delete json.password2; data.push(json); alert(JSON.stringify(data)); $.ajax({ url: '${pageContext.request.contextPath}/register-controller', type: 'POST', data: JSON.stringify(data), // 将JS对象序列化为JSON字符串 dataType: 'json', contentType: 'application/json', mimeType: 'application/json', error: function(xhr, status, error) { console.log("请求错误:", status, error); console.log("响应内容:", xhr.responseText); } }); });
3. Servlet接收JSON数据方式错误
当前Servlet使用request.getParameter("data")获取数据,但JSON请求的内容是放在请求体中,而非URL参数里,因此无法通过getParameter获取。
修复代码(RegisterController.java):
@WebServlet(name = "registerController", value = "/register-controller") public class RegisterController extends HttpServlet { private UserJsonUtils jsonUtils; private User data; private UserDao userDao; final String userPath = "src/model/user/users.json"; public void init() { jsonUtils = new UserJsonUtils(); userDao = new UserDao(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 读取请求体中的JSON字符串 BufferedReader reader = request.getReader(); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } String jsonStr = sb.toString(); // 解析前端传来的JSON数组 User[] users = jsonUtils.parseJsonArray(jsonStr); if (users != null && users.length > 0) { data = users[0]; register(); } // 返回成功响应给前端 response.setContentType("application/json"); response.getWriter().write("{\"status\":\"success\"}"); } public void register() { User user = new User(data.getFirstName(), data.getLastName(), data.getEmail(), data.getPassword()); userDao.save(user); } }
同时修改UserJsonUtils.java,添加数组解析方法:
public class UserJsonUtils { private User data; public UserJsonUtils() { } public User getData() { return data; } public void setData(User data) { this.data = data; } public User parseJson(String params) { Gson gson = new Gson(); data = gson.fromJson(params, User.class); return data; } // 添加解析JSON数组的方法 public User[] parseJsonArray(String params) { Gson gson = new Gson(); return gson.fromJson(params, User[].class); } public void writeToFile(String path, User user) throws IOException { Gson gson = new Gson(); gson.toJson(user, new FileWriter(path)); } }
4. Servlet API版本与Tomcat9不兼容
Tomcat9仅支持Servlet 4.0(javax.servlet),但你的pom.xml中使用的是Jakarta Servlet 5.0(jakarta.servlet-api),这是Tomcat10及以上版本才支持的,会导致Servlet无法被Tomcat正确识别注册。
修复代码(pom.xml):
替换Servlet API依赖:
<!-- 替换原Jakarta依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
同时,确保RegisterController中的import是javax.servlet相关包:
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException;
验证步骤
- 重新编译部署项目到Tomcat9
- 打开Chrome开发者工具(F12),切换到Network标签
- 填写表单并点击Register按钮,查看是否有
register-controller的请求,状态码是否为200 - 检查数据库是否新增了用户数据
内容的提问来源于stack exchange,提问作者F.M

