表单提交404错误详细整理,错误URL
问题:表单提交404错误详细整理
问题现象
错误表现
- 正常访问:
http://localhost:8080/bank/transfer.jsp
页面可以正常打开 - 表单提交后:浏览器跳转到404页面
- 错误URL:
http://localhost:8080/bank/%20%20%20%20//localhost:8080/bank/transfer
- URL解码:
%20%20%20%20
= 4个空格
问题分析
1. URL结构分析
原始URL:http://localhost:8080/bank/%20%20%20%20//localhost:8080/bank/transfer
解码后:http://localhost:8080/bank/ //localhost:8080/bank/transfer
2. 问题根源
- 前端问题:HTML表单的
action
属性设置错误 - 具体原因:
action
属性值包含多余空格和重复的完整URL路径
解决方案
方案1:修复HTML表单代码
错误的代码示例:
<!-- 错误1:action前面有多个空格 -->
<form action=" /bank/transfer" method="post"><!-- 表单内容 -->
</form><!-- 错误2:包含完整URL且有多余空格 -->
<form action=" http://localhost:8080/bank/transfer" method="post"><!-- 表单内容 -->
</form><!-- 错误3:重复协议和主机名 -->
<form action=" //localhost:8080/bank/transfer" method="post"><!-- 表单内容 -->
</form>
正确的代码写法:
<!-- 方法1:相对路径(推荐) -->
<form action="transfer" method="post"><input type="text" name="toAccount"><input type="number" name="amount"><input type="submit" value="转账">
</form><!-- 方法2:绝对路径 -->
<form action="/bank/transfer" method="post"><!-- 表单内容 -->
</form><!-- 方法3:使用JSP动态路径(最灵活) -->
<form action="${pageContext.request.contextPath}/transfer" method="post"><!-- 表单内容 -->
</form><!-- 方法4:当前目录相对路径 -->
<form action="./transfer" method="post"><!-- 表单内容 -->
</form>
方案2:检查并配置Servlet
确保Servlet正确映射:
// 方法1:使用注解(推荐)
@WebServlet("/transfer")
public class TransferServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 获取表单参数String toAccount = request.getParameter("toAccount");String amount = request.getParameter("amount");// 处理业务逻辑boolean success = transferService.doTransfer(toAccount, amount);// 返回结果if (success) {response.sendRedirect("success.jsp");} else {response.sendRedirect("error.jsp");}}
}
<!-- 方法2:使用web.xml配置 -->
<servlet><servlet-name>TransferServlet</servlet-name><servlet-class>com.bank.TransferServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>TransferServlet</servlet-name><url-pattern>/transfer</url-pattern>
</servlet-mapping>
方案3:完整的正确示例
transfer.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>转账页面</title>
</head>
<body><h2>银行转账</h2><!-- 正确的表单 --><form action="transfer" method="post"><table><tr><td>收款账户:</td><td><input type="text" name="toAccount" required></td></tr><tr><td>转账金额:</td><td><input type="number" name="amount" step="0.01" min="0.01" required></td></tr><tr><td colspan="2"><input type="submit" value="确认转账"><input type="reset" value="重置"></td></tr></table></form>
</body>
</html>
TransferServlet.java:
package com.bank.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.IOException;@WebServlet("/transfer")
public class TransferServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 设置字符编码request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");// 获取表单参数String toAccount = request.getParameter("toAccount");String amountStr = request.getParameter("amount");try {double amount = Double.parseDouble(amountStr);// 调用业务逻辑处理转账boolean success = processTransfer(toAccount, amount);if (success) {// 转账成功,跳转到成功页面response.sendRedirect("success.jsp");} else {// 转账失败,跳转到失败页面response.sendRedirect("error.jsp?reason=transfer_failed");}} catch (NumberFormatException e) {// 金额格式错误response.sendRedirect("error.jsp?reason=invalid_amount");}}private boolean processTransfer(String toAccount, double amount) {// 这里实现具体的转账业务逻辑// 返回true表示转账成功,false表示失败return true; // 示例返回值}
}
排查步骤
步骤1:检查页面源代码
在浏览器中右键 → 查看页面源代码,搜索<form
标签:
<!-- 找到表单代码,检查action属性 -->
<form action=" //localhost:8080/bank/transfer" method="post">
步骤2:修复代码
将错误的action属性修正为:
<form action="transfer" method="post">
步骤3:验证修复
- 重新部署应用
- 访问转账页面
- 填写表单并提交
- 检查URL是否正确跳转到:
http://localhost:8080/bank/transfer
步骤4:测试不同场景
<!-- 测试各种路径写法 -->
<form action="transfer" method="post">测试1</form>
<form action="./transfer" method="post">测试2</form>
<form action="/bank/transfer" method="post">测试3</form>
预防措施
1. 使用统一的路径管理
<!-- 在页面顶部定义基础路径 -->
<c:set var="basePath" value="${pageContext.request.contextPath}" /><!-- 在所有链接和表单中使用 -->
<form action="${basePath}/transfer" method="post">
<a href="${basePath}/index.jsp">首页</a>
2. 代码规范检查
- 在IDE中配置HTML代码格式化
- 使用代码检查工具确保没有多余空格
- 建立团队代码规范
3. 测试策略
- 对所有表单提交功能进行测试
- 检查生成的URL是否正确
- 验证Servlet映射是否准确
常见错误模式总结
错误类型 | 错误示例 | 正确写法 |
---|---|---|
多余空格 | action=" /transfer" | action="transfer" |
重复URL | action="http://localhost:8080/bank/transfer" | action="transfer" |
缺少上下文 | action="/transfer" | action="transfer" |
路径错误 | action="../transfer" | action="transfer" |
通过以上详细的整理和解决方案,应该能够彻底解决表单提交404错误的问题。