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

JSTL c:forEach循环end属性绑定EL表达式计算值仅执行一次问题

问题根因

  1. JSTL标准函数库中的fn:replace仅支持普通字符串替换,不支持正则表达式语法,你写的${fn:replace(data, '[^,]', '')}无法实现“删除所有非逗号字符”的效果,得到的count变量并非预期的仅含逗号的字符串,fn:length(count)的结果不符合预期。
  2. 部分JSTL版本中,动态计算的数值如果没有显式声明为整数类型,c:forEach的end属性会将其识别为字符串类型,导致解析错误、循环次数异常。

解决方案

这里提供两种可行方案,优先推荐第一种:

方案1:直接遍历拆分后的数组(最优,无边界计算问题)

你已经用fn:split将字符串拆分为了数组,直接遍历数组即可,无需手动计算循环边界:

<b:dataTableColumn label="Misc. Documents: " >
    <c:set var="data" value="#{item.miscDocs}"/>
    <c:set var="splitPart" value="${fn:split(data, ',')}"/>
    <c:forEach items="${splitPart}" var="docPart">
        <a href="/homekey/${docPart}">${fn:replace(docPart, '%20', ' ')}</a><br/>
    </c:forEach>
</b:dataTableColumn>

该写法天然适配拆分后的元素数量,不会出现越界、循环次数不对的问题。

方案2:修正逗号计数逻辑并显式转换数值类型

如果你需要保留索引遍历的写法,按如下步骤修改:

  1. 用字符串长度差的方式计算逗号数量,该方法不需要正则,兼容所有JSTL版本
  2. 显式将计数结果转为整数类型,避免end属性识别异常
    修改后的代码如下:
<!-- 需先引入fmt标签库,放在页面顶部 -->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<b:dataTableColumn label="Misc. Documents: " >
    <c:set var="data" value="#{item.miscDocs}"/>
    <c:set var="splitPart" value="${fn:split(data, ',')}"/>
    <!-- 用原字符串长度减去删除所有逗号后的字符串长度,得到逗号数量 -->
    <c:set var="commaCount" value="${fn:length(data) - fn:length(fn:replace(data, ',', ''))}"/>
    <!-- 显式转为整数 -->
    <fmt:parseNumber var="max" value="${commaCount}" integerOnly="true" />
    <c:forEach var = "i" begin = "0" end = "${max}">
        <a href="/homekey/${splitPart[i]}">${fn:replace(splitPart[i], '%20', ' ')}</a><br/>
    </c:forEach>
</b:dataTableColumn>

内容的提问来源于stack exchange,提问作者Zack T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:45:08