【问题标题】:accessing constants in JSP (without scriptlet) [duplicate]访问 JSP 中的常量(没有 scriptlet)[重复]
【发布时间】:2010-09-12 10:38:23
【问题描述】:

我有一个定义各种会话属性名称的类,例如

class Constants {
    public static final String ATTR_CURRENT_USER = "current.user";
}

我想在 JSP 中使用这些常量来测试这些属性是否存在,例如:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="com.example.Constants" %>

<c:if test="${sessionScope[Constants.ATTR_CURRENT_USER] eq null}">
    <%-- Do somthing --%>
</c:if>

但我似乎无法正确获取语法。此外,为了避免在多个地方重复上述相当冗长的测试,我想将结果分配给本地(页面范围)变量,并改为引用它。我相信我可以使用 &lt;c:set&gt; 做到这一点,但我再次努力寻找正确的语法。

更新:根据以下建议,我尝试了:

<c:set var="nullUser" scope="session"
value="${sessionScope[Constants.ATTR_CURRENT_USER] eq null}" />

这没有用。因此,我尝试替换常量的字面值。我还将常量添加到页面的内容中,以便在呈现页面时验证常量的值

<c:set var="nullUser" scope="session"
value="${sessionScope['current.user'] eq null}" />
<%= "Constant value: " + WebHelper.ATTR_CURRENT_PARTNER %>

这很好,它在页面上打印了预期值“current.user”。我无法解释为什么使用字符串文字有效,但是当两者似乎具有相同的值时,对常量的引用却不起作用。帮助.....

【问题讨论】:

    标签: java jsp session jstl


    【解决方案1】:

    它在您的示例中不起作用,因为 ATTR_CURRENT_USER 常量对 JSTL 标记不可见,这些标记期望属性由 getter 函数公开。我还没有尝试过,但公开常量的最简洁方法似乎是unstandard tag library

    ETA:我提供的旧链接无效。可以在此答案中找到新链接:Java constants in JSP

    编写 sn-ps 代码以阐明您所看到的行为: 示例类:

    package com.example;
    
    public class Constants
    {
        // attribute, visible to the scriptlet
        public static final String ATTR_CURRENT_USER = "current.user";
    
        // getter function;
        // name modified to make it clear, later on, 
        // that I am calling this function
        // and not accessing the constant
        public String getATTR_CURRENT_USER_FUNC()
        {
            return ATTR_CURRENT_USER;
        }
    
    
    }    
    

    JSP 页面的片段,显示示例用法:

    <%-- Set up the current user --%>
    <%
        session.setAttribute("current.user", "Me");
    %>
    
    <%-- scriptlets --%>
    <%@ page import="com.example.Constants" %>
    <h1>Using scriptlets</h1>
    <h3>Constants.ATTR_CURRENT_USER</h3>
    <%=Constants.ATTR_CURRENT_USER%> <br />
    <h3>Session[Constants.ATTR_CURRENT_USER]</h3>
    <%=session.getAttribute(Constants.ATTR_CURRENT_USER)%>
    
    <%-- JSTL --%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <jsp:useBean id="cons" class="com.example.Constants" scope="session"/>
    
    <h1>Using JSTL</h1>
    <h3>Constants.getATTR_CURRENT_USER_FUNC()</h3>
    <c:out value="${cons.ATTR_CURRENT_USER_FUNC}"/>
    <h3>Session[Constants.getATTR_CURRENT_USER_FUNC()]</h3>
    <c:out value="${sessionScope[cons.ATTR_CURRENT_USER_FUNC]}"/>
    <h3>Constants.ATTR_CURRENT_USER</h3>
    <c:out value="${sessionScope[Constants.ATTR_CURRENT_USER]}"/>
    <%--
    Commented out, because otherwise will error:
    The class 'com.example.Constants' does not have the property 'ATTR_CURRENT_USER'.
    
    <h3>cons.ATTR_CURRENT_USER</h3>
    <c:out value="${sessionScope[cons.ATTR_CURRENT_USER]}"/>
    --%>
    <hr />
    

    这个输出:

    使用小脚本

    常量.ATTR_CURRENT_USER

    当前用户

    会话[Constants.ATTR_CURRENT_USER]


    使用 JSTL

    Constants.getATTR_CURRENT_USER_FUNC()

    当前用户

    会话[Constants.getATTR_CURRENT_USER_FUNC()]

    常量.ATTR_CURRENT_USER



    【讨论】:

    • 很棒的答案!好像没找到下载非标准taglib的方法,不知道现在还能用吗?
    【解决方案2】:

    您可以使用 c:set 将 Constants.ATTR_CURRENT_USER 定义为变量,如下所示:

    <c:set var="ATTR_CURRENT_USER" value="<%=Constants.ATTR_CURRENT_USER%>" />
    <c:if test="${sessionScope[ATTR_CURRENT_USER] eq null}">     
        <%-- Do somthing --%> 
    </c:if> 
    

    【讨论】:

      【解决方案3】:

      这个话题很老了,但无论如何..:)

      我找到了通过 JSTL 提供常量的好方法。您应该使用反射准备地图并将其放置在您想要的任何位置。

      映射将始终包含您在常量类中定义的所有常量。您可以使用侦听器将其放入 ServletContext 并享受 JSTL 中的常量,例如:

      ${CONSTANTS["CONSTANT_NAME_IN_JAVA_CLASS_AS_A_STRING"]}
      


      这里的 CONSTANTS 是您将地图放入 Context 时使用的键 :-)


      以下是我构建常量字段映射的一段代码:

      Map<String, Object> map = new HashMap<String, Object>();
      Class c = Constants.class;
      Field[] fields = c.getDeclaredFields();
      for (Field field : fields) {
         int modifier = field.getModifiers();
         if (Modifier.isPublic(modifier) && Modifier.isStatic(modifier) && Modifier.isFinal(modifier)) {
            try {
               map.put(field.getName(), field.get(null));//Obj param of get method is ignored for static fields
            } catch (IllegalAccessException e) { /* ignorable due to modifiers check */ }
         }
      }
      

      【讨论】:

        【解决方案4】:

        我迟到了讨论,但我的方法有点不同。我使用自定义标记处理程序为 JSP 页面提供所需的常量值(数字或字符串)。这是我的做法:

        假设我有一个保留所有常量的类:

        public class AppJspConstants implements Serializable {
            public static final int MAXLENGTH_SIGNON_ID = 100;
            public static final int MAXLENGTH_PASSWORD = 100;
            public static final int MAXLENGTH_FULLNAME = 30;
            public static final int MAXLENGTH_PHONENUMBER = 30;
            public static final int MAXLENGTH_EXTENSION = 10;
            public static final int MAXLENGTH_EMAIL = 235;
        }
        

        我也有这个非常简单的自定义标签:

        public class JspFieldAttributes extends SimpleTagSupport {
            public void doTag() throws JspException, IOException {
                getJspContext().setAttribute("maxlength_signon_id", AppJspConstants.MAXLENGTH_SIGNON_ID);
                getJspContext().setAttribute("maxlength_password", AppJspConstants.MAXLENGTH_PASSWORD);
                getJspContext().setAttribute("maxlength_fullname", AppJspConstants.MAXLENGTH_FULLNAME);
                getJspContext().setAttribute("maxlength_phonenumber", AppJspConstants.MAXLENGTH_PHONENUMBER);
                getJspContext().setAttribute("maxlength_extension", AppJspConstants.MAXLENGTH_EXTENSION);
                getJspContext().setAttribute("maxlength_email", AppJspConstants.MAXLENGTH_EMAIL);
        
                getJspBody().invoke(null);
            }
        }
        

        然后我有一个 StringHelper.tld。在里面,我有这个:

        <tag>
            <name>fieldAttributes</name>
            <tag-class>package.path.JspFieldAttributes</tag-class>
            <body-content>scriptless</body-content>
            <info>This tag provide HTML field attributes that CCS is unable to do.</info>
        </tag>
        

        在 JSP 上,我以正常方式包含 StringHelper.tld:

        <%@ taglib uri="/WEB-INF/tags/StringHelper.tld" prefix="stringHelper" %>
        

        最后,我使用标签并使用 EL 应用所需的值。

                <stringHelper:fieldAttributes>
        [snip]
                    <form:input path="emailAddress" cssClass="formeffect" cssErrorClass="formEffect error" maxlength="**${maxlength_email}**"/>&nbsp;
                    <form:errors path="emailAddress" cssClass="error" element="span"/>
        [snip]
                </stringHelper:fieldAttributes>
        

        【讨论】:

          【解决方案5】:

          将自定义 EL 解析器插入 EL 解析器链,它将解析常量。 EL Resolver 是扩展 javax.el.ELResolver 类的 Java 类。

          谢谢,

          【讨论】:

          • 您可以添加任何文档或发布有关此的链接吗?提前坦克。
          【解决方案6】:

          在 EL 中无法访问静态属性。我使用的解决方法是创建一个将自身分配给静态值的非静态变量。

          public final static String MANAGER_ROLE = 'manager';
          public String manager_role = MANAGER_ROLE;
          

          我使用 lombok 来生成 getter 和 setter,这样就很好了。你的 EL 看起来像这样:

          ${bean.manager_role}
          

          完整代码https://rogerkeays.com/access-java-static-methods-and-constants-from-el

          【讨论】:

            【解决方案7】:

            首先,您的语法有一个额外的“]”导致错误。

            要解决这个问题,并设置一个变量,您可以这样做:

            <c:set var="nullUser" 
                scope="session" 
                value="${sessionScope[Constants.ATTR_CURRENT_USER] eq null}" />
            
            <c:if test="${nullUser}">
                 <h2>First Test</h2>
            </c:if>
            <c:if test="${nullUser}">
                 <h2>Another Test</h2>
            </c:if>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-05-20
              • 2011-11-09
              • 2013-01-14
              • 1970-01-01
              • 1970-01-01
              • 2015-12-02
              • 2010-09-12
              相关资源
              最近更新 更多