Доступ к константам в JSP (без скриптлета)
У меня есть класс, который определяет имена различных атрибутов сеанса, например
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>
Но я не могу понять правильный синтаксис. Кроме того, чтобы избежать повторения довольно длинных тестов, описанных выше, в нескольких местах, я хотел бы присвоить результат локальной переменной (в области страницы) и вместо этого ссылаться на нее. Я верю, что могу сделать это с <c:set>
, но я снова пытаюсь найти правильный синтаксис.
ОБНОВЛЕНИЕ: В дополнение к предложению ниже, я попытался:
<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" на странице. Я затрудняюсь объяснить, почему я использую строковые литералы, но ссылка на константу - нет, когда они имеют одинаковое значение. Помогите.....
7 ответов
Это не работает в вашем примере, потому что ATTR_CURRENT_USER
константа не видна тегам JSTL, которые ожидают, что свойства будут выставлены функциями получения. Я не пробовал, но самый простой способ показать ваши константы - это нестандартная библиотека тегов.
ETA: Старая ссылка, которую я дал, не сработала. В этом ответе можно найти новые ссылки: константы Java в JSP
Фрагменты кода, чтобы прояснить поведение, которое вы видите: Пример класса:
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 />
Это выводит:
Использование скриптлетов
Constants.ATTR_CURRENT_USER
текущий пользователь
Секция [Constants.ATTR_CURRENT_USER]
мне
Использование JSTL
Constants.getATTR_CURRENT_USER_FUNC ()
текущий пользователь
Секция [Constants.getATTR_CURRENT_USER_FUNC()]
мне
Constants.ATTR_CURRENT_USER
Вы можете определить Constants.ATTR_CURRENT_USER как переменную с помощью c:set, как показано ниже:
<c:set var="ATTR_CURRENT_USER" value="<%=Constants.ATTR_CURRENT_USER%>" />
<c:if test="${sessionScope[ATTR_CURRENT_USER] eq null}">
<%-- Do somthing --%>
</c:if>
Тема довольно старая, но все равно..:)
Я нашел хорошее решение, чтобы Константы были доступны через JSTL. Вы должны подготовить карту, используя отражение, и поместить ее в любое место.
Карта всегда будет содержать все константы, которые вы определили в классе Constants. Вы можете поместить его в 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 */ }
}
}
Я опаздываю к обсуждению, но мой подход немного отличается. Я использую собственный обработчик тегов, чтобы дать 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}**"/>
<form:errors path="emailAddress" cssClass="error" element="span"/>
[snip]
</stringHelper:fieldAttributes>
Подключите пользовательский EL Resolver к цепочке распознавателя EL, которая разрешит константы. EL Resolver - это класс Java, расширяющий класс javax.el.ELResolver.
Спасибо,
Статические свойства не доступны в EL. Обходной путь, который я использую, заключается в создании нестатической переменной, которая присваивает себя статическому значению.
public final static String MANAGER_ROLE = 'manager';
public String manager_role = MANAGER_ROLE;
Я использую lombok для генерации геттера и сеттера, так что это довольно хорошо. Ваш EL выглядит так:
${bean.manager_role}
Полный код на http://www.ninthavenue.com.au/java-static-constants-in-jsp-and-jsf-el
Во-первых, у вашего синтаксиса был дополнительный символ "]", который вызывал ошибку.
Чтобы исправить это и установить переменную, вы должны сделать это:
<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>