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

JSP多行表格表单提交始终传递首行数据到Servlet问题排查

问题根因

问题核心是所有行的表单元素都放在了同一个

容器里。
浏览器提交表单时,会把容器内所有同name属性的参数全部上传,而Servlet的request.getParameter()方法遇到重名参数时,默认只会返回第一个匹配的值,这就是点任何行的提交按钮,后端拿到的都是第一行数据的直接原因。
另外还有两个会触发崩溃的问题:

1. 前端改造:每行独立绑定表单,避免参数冲突

因为HTML规范不允许标签直接作为的子元素,最稳妥的写法是给每一行生成独立的表单,通过HTML5的form属性把当前行的输入框和对应表单关联,提交时只会上传当前行的参数。
修正后的JSP代码:

<table border="1">
<tr>
    <th>Currency</th>
    <th>Rate</th>
    <th>Amount</th>
    <th>Action</th>
</tr>
<c:forEach var="tempValue" items="${kalkulatorList}" varStatus="counter">
    <tr>
        <td>
            <input type="hidden" name="currency" value="${tempValue.currency}" form="exchange_${tempValue.id}">
            ${tempValue.currency}
        </td>
        <td>
            <input type="hidden" name="rates" value="${tempValue.rates}" form="exchange_${tempValue.id}">
            ${tempValue.rates}
        </td>
        <td>
            <input type="number" name="amount" placeholder="enter amount" form="exchange_${tempValue.id}"/>
        </td>
        <td>
            <form action="/exchangeServlet" method="post" id="exchange_${tempValue.id}" style="display:inline;margin:0">
                <input type="hidden" name="id" value="${tempValue.id}">
                <input type="submit" value="Exchange">
            </form>
        </td>
    </tr>
</c:forEach>
</table>

如果要兼容不支持form属性的极低版本浏览器,直接把当前行所有隐藏域和提交按钮都放到操作列的form内部即可,隐藏域不需要和显示的文本放在同一个里,不影响参数提交。

2. 后端加兜底校验,避免程序崩溃

不管前端逻辑怎么写,后端必须做参数合法性校验,禁止直接拿到参数就转数字,从根源上避免空值、非法值导致的服务崩溃:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/plain;charset=utf-8");
    PrintWriter printWriter = response.getWriter();
    try {
        String currency = request.getParameter("currency");
        String idStr = request.getParameter("id");
        String ratesStr = request.getParameter("rates");
        String amountStr = request.getParameter("amount");
        
        // 空值校验
        if (currency == null || idStr == null || ratesStr == null || amountStr == null
                || currency.isBlank() || idStr.isBlank() || ratesStr.isBlank() || amountStr.isBlank()) {
            printWriter.write("提交参数缺失,请重试");
            return;
        }

        int id = Integer.parseInt(idStr.trim());
        float rates = Float.parseFloat(ratesStr.trim());
        float amount = Float.parseFloat(amountStr.trim());
        float euro = amount * rates;

        printWriter.append(String.valueOf(id)).append(" : ");
        printWriter.append(currency).append(" - ");
        printWriter.append("rate : ").append(String.valueOf(rates));
        printWriter.append(" ---> You have got ").append(String.valueOf(euro)).append(" Euros");
    } catch (NumberFormatException e) {
        printWriter.write("参数格式错误,请输入合法的数字金额");
    }
}
避坑提醒

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:09:17