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

JSF与JSTL在XHTML页面中c:choose条件判断异常问题

JSF中<c:choose>条件判断不符合预期的排查与解决

问题现象

使用JSF开发XHTML页面时,发现<c:choose>标签内的<c:when>条件${pwaService.isTicketFromUser(tik.from) eq true},在后台方法实际返回false时,页面仍渲染right-msg区块,而非<c:otherwise>对应的left-msg区块。后台isTicketFromUser方法逻辑已验证可正常返回true或false,但页面表现不符合预期。

相关代码

页面头部标签

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
>

<c:choose>代码片段

<c:forEach items="#{pwaService.tickets}" var="tik">
    <c:choose>
        <c:when test="${pwaService.isTicketFromUser(tik.from) eq true}">
            <div class="msg right-msg">
                <div class="msg-bubble">
                    <div class="msg-info">
                        <div class="msg-info-name">#{tik.from.name}</div>
                        <div class="msg-info-time">#{pwaService.time(tik.sentDate)}</div>
                    </div>
                    <div class="msg-text">
                        #{tik.message}
                    </div>
                </div>
            </div>
        </c:when>
        <c:otherwise>
            <div class="msg left-msg">
                <div class="msg-bubble">
                    <div class="msg-info">
                        <div class="msg-info-name">مدیر سامانه</div>
                        <div class="msg-info-time">#{pwaService.time(tik.sentDate)}</div>
                    </div>
                    <div class="msg-text">
                        #{tik.message}
                    </div>
                </div>
            </div>
        </c:otherwise>
    </c:choose>
</c:forEach>

后台Java方法

public boolean isTicketFromUser(User from) {
    return !from.getId().equals(UUID.fromString("hiddenUUID"));
}

排查与解决思路

1. 简化EL布尔条件判断

EL表达式中,布尔类型的方法返回值无需额外与true做比较。原条件${pwaService.isTicketFromUser(tik.from) eq true}可以直接简化为${pwaService.isTicketFromUser(tik.from)}。

多余的eq true可能引发EL类型转换异常:若方法返回的Boolean包装类为null,EL会将其转换为false,但某些容器的转换逻辑可能出现偏差,导致判断结果不符合预期。简化后能避免这类潜在问题。

2. 替换JSTL标签为JSF原生组件适配生命周期

JSTL标签(<c:forEach>、<c:choose>)在视图构建阶段执行,而JSF的数据绑定逻辑在视图渲染阶段生效。如果pwaService.tickets的数据是在渲染阶段才完成加载,JSTL会提前基于未初始化的旧数据执行判断,导致页面渲染错误。

建议替换为JSF原生的<ui:repeat>和<h:panelGroup rendered>实现条件渲染:

<ui:repeat value="#{pwaService.tickets}" var="tik">
    <h:panelGroup rendered="#{pwaService.isTicketFromUser(tik.from)}">
        <div class="msg right-msg">
            <div class="msg-bubble">
                <div class="msg-info">
                    <div class="msg-info-name">#{tik.from.name}</div>
                    <div class="msg-info-time">#{pwaService.time(tik.sentDate)}</div>
                </div>
                <div class="msg-text">
                    #{tik.message}
                </div>
            </div>
        </div>
    </h:panelGroup>
    <h:panelGroup rendered="#{!pwaService.isTicketFromUser(tik.from)}">
        <div class="msg left-msg">
            <div class="msg-bubble">
                <div class="msg-info">
                    <div class="msg-info-name">مدیر سامانه</div>
                    <div class="msg-info-time">#{pwaService.time(tik.sentDate)}</div>
                </div>
                <div class="msg-text">
                    #{tik.message}
                </div>
            </div>
        </div>
    </h:panelGroup>
</ui:repeat>

3. 验证方法参数的有效性

确认tik.from在JSTL执行阶段是否已正确初始化:

  • 在isTicketFromUser方法中添加日志,输出from的ID值,检查参数是否为null或非预期值;
  • 若tik.from为null,调用from.getId()会抛出空指针异常,EL会静默处理该异常并返回false,但实际页面可能因为异常导致判断逻辑异常。可在方法中添加非空判断:
public boolean isTicketFromUser(User from) {
    if (from == null) {
        return false; // 或根据业务逻辑返回对应值
    }
    return !from.getId().equals(UUID.fromString("hiddenUUID"));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:35:19