12 ответов:
EL 3.0 или новее
если вы уже на Java EE 7 / EL 3.0, то
@page importтакже будет импортировать константы класса в области EL.<%@ page import="com.example.YourConstants" %>это будет под крышками импортироваться через
ImportHandler#importClass()и быть доступным как${YourConstants.FOO}.обратите внимание, что все
java.lang.*классы уже неявно импортированы и доступны так${Boolean.TRUE}и${Integer.MAX_VALUE}. Для этого требуется только более поздний сервер контейнеров Java EE 7, так как в ранних версиях были ошибки этот. Например, GlassFish 4.0 и Tomcat 8.0.0-1x терпит неудачу, но GlassFish 4.1+ и Tomcat 8.0.2 x+ работает. И вы должны быть абсолютно уверены, что вашweb.xmlобъявляется соответствие последней версии сервлета, поддерживаемой сервером. Таким образом, сweb.xmlкоторый объявлен соответствующим сервлетом 2.5 или старше, ни одна из функций сервлета 3.0+ не будет работать.также обратите внимание, что этот объект доступен только в JSP, а не в Facelets. В случае JSF + Facelets, лучше всего использовать OmniFaces
<o:importConstants>как показано ниже:<o:importConstants type="com.example.YourConstants" />или добавление слушателя контекста EL, который вызывает
ImportHandler#importClass()как показано ниже:@ManagedBean(eager=true) @ApplicationScoped public class Config { @PostConstruct public void init() { FacesContext.getCurrentInstance().getApplication().addELContextListener(new ELContextListener() { @Override public void contextCreated(ELContextEvent event) { event.getELContext().getImportHandler().importClass("com.example.YourConstants"); } }); } }
EL 2.2 или старше
это не возможно в EL 2.2 и старше. Есть несколько вариантов:
их в
Map<String, Object>который вы помещаете в область применения. В EL Значения карты доступны обычным способом Javabean с помощью${map.key}или${map['key.with.dots']}.использовать
<un:useConstants>на Unstandard taglib (maven2 repo здесь):<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %> <un:useConstants className="com.example.YourConstants" var="constants" />таким образом, они доступны обычным Javabean способом
${constants.FOO}.использовать Javaranch это CCC
<ccc:constantsMap>как описано где-то внизу в этой статье.<%@ taglib uri="http://bibeault.org/tld/ccc" prefix="ccc" %> <ccc:constantsMap className="com.example.YourConstants" var="constants" />таким образом они доступны обычным Javabean way by
${constants.FOO}как хорошо.если вы используете JSF2, то вы могли бы использовать
<o:importConstants>на OmniFaces.<html ... xmlns:o="http://omnifaces.org/ui"> <o:importConstants type="com.example.YourConstants" />таким образом, они доступны обычным Javabean способом
#{YourConstants.FOO}как хорошо.создайте класс-оболочку, который возвращает их через методы getter в стиле Javabean.
создайте пользовательский El-преобразователь, который сначала сканирует наличие константа и если отсутствует, то делегировать в Преобразователь по умолчанию, в противном случае возвращает значение константы вместо этого.
вы обычно помещаете эти виды констант в
Configurationобъект (который имеет геттеры и сеттеры) в контекст сервлета, и доступ к ним с${applicationScope.config.url}
следующее не относится к EL в целом, а только к SpEL (Spring EL) (проверено с помощью 3.2.2.Релиз на Tomcat 7). Я думаю, что стоит упомянуть об этом здесь, Если кто-то ищет JSP и EL (но использует JSP с Spring).
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <spring:eval var="constant" expression="T(com.example.Constants).CONSTANT"/>
статические свойства недоступны в EL. Обходной путь, который я использую, заключается в создании нестатической переменной, которая присваивает себе статическое значение.
public final static String MANAGER_ROLE = 'manager'; public String manager_role = MANAGER_ROLE;Я использую Ломбок для создания геттера и сеттера, так что это довольно хорошо. Ваш EL выглядит так:
${bean.manager_role}полный код на http://www.ninthavenue.com.au/java-static-constants-in-jsp-and-jsf-el
я реализовал так:
public interface Constants{ Integer PAGE_SIZE = 20; }-
public class JspConstants extends HashMap<String, String> { public JspConstants() { 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 { Object o = field.get(null); put(field.getName(), o != null ? o.toString() : null); } catch(IllegalAccessException ignored) { } } } } @Override public String get(Object key) { String result = super.get(key); if(StringUtils.isEmpty(result)) { throw new IllegalArgumentException("Check key! The key is wrong, no such constant!"); } return result; } }следующий шаг поместите экземпляр этого класса в servlerContext
public class ApplicationInitializer implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { sce.getServletContext().setAttribute("Constants", new JspConstants()); } @Override public void contextDestroyed(ServletContextEvent sce) { } }добавить слушателя в интернете.xml
<listener> <listener-class>com.example.ApplicationInitializer</listener-class> </listener>доступ в jsp
${Constants.PAGE_SIZE}
Да, вы можете. Вам нужен пользовательский тег (если вы не можете найти его где-то еще). Я сделал это:
package something; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Map; import java.util.TreeMap; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import org.apache.taglibs.standard.tag.el.core.ExpressionUtil; /** * Get all class constants (statics) and place into Map so they can be accessed * from EL. * @author Tim.sabin */ public class ConstMapTag extends TagSupport { public static final long serialVersionUID = 0x2ed23c0f306L; private String path = ""; private String var = ""; public void setPath (String path) throws JspException { this.path = (String)ExpressionUtil.evalNotNull ("constMap", "path", path, String.class, this, pageContext); } public void setVar (String var) throws JspException { this.var = (String)ExpressionUtil.evalNotNull ("constMap", "var", var, String.class, this, pageContext); } public int doStartTag () throws JspException { // Use Reflection to look up the desired field. try { Class<?> clazz = null; try { clazz = Class.forName (path); } catch (ClassNotFoundException ex) { throw new JspException ("Class " + path + " not found."); } Field [] flds = clazz.getDeclaredFields (); // Go through all the fields, and put static ones in a Map. Map<String, Object> constMap = new TreeMap<String, Object> (); for (int i = 0; i < flds.length; i++) { // Check to see if this is public static final. If not, it's not a constant. int mods = flds [i].getModifiers (); if (!Modifier.isFinal (mods) || !Modifier.isStatic (mods) || !Modifier.isPublic (mods)) { continue; } Object val = null; try { val = flds [i].get (null); // null for static fields. } catch (Exception ex) { System.out.println ("Problem getting value of " + flds [i].getName ()); continue; } // flds [i].get () automatically wraps primitives. // Place the constant into the Map. constMap.put (flds [i].getName (), val); } // Export the Map as a Page variable. pageContext.setAttribute (var, constMap); } catch (Exception ex) { if (!(ex instanceof JspException)) { throw new JspException ("Could not process constants from class " + path); } else { throw (JspException)ex; } } return SKIP_BODY; } }и тег называется:
<yourLib:constMap path="path.to.your.constantClass" var="consts" />все общедоступные статические конечные переменные будут помещены в карту, индексированную их именем Java, поэтому если
public static final int MY_FIFTEEN = 15;тогда тег обернет это в целое число, и вы можете ссылаться на него в JSP:
<c:if test="${consts['MY_FIFTEEN'] eq 15}">и вам не нужно писать геттеры!
вы можете. Попробовать на следующим образом
#{T(com.example.Addresses).URL}протестировано на TomCat 7 и java6
Я определяю константу в моем jsp прямо в начале:
<%final String URI = "http://www.example.com/";%>Я включает основные библиотеки тегов в моем ССП:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>затем я делаю константу доступной для EL следующим утверждением:
<c:set var="URI" value="<%=URI%>"></c:set>теперь, я могу использовать его позже. Вот пример, где значение просто записывается как HTML-комментарий для целей отладки:
<!-- ${URI} -->
С вашим постоянным классом вы можете просто импортировать свой класс и назначить константы локальным переменная. Я знаю, что мой ответ-это своего рода быстрый хак, но вопрос также возникает, когда нужно определить константы непосредственно в JSP.
даже зная его немного поздно, и даже зная, что это немного взломать - я использовал следующее решение для достижения желаемого результата. Если вы любитель Java-именования-конвенций, мой совет-прекратить читать здесь...
имея такой класс, определяя константы, сгруппированные по пустым классам, чтобы создать своего рода иерархию:
public class PERMISSION{ public static class PAGE{ public static final Long SEE = 1L; public static final Long EDIT = 2L; public static final Long DELETE = 4L; ... } }может использоваться из java как
PERMISSION.PAGE.SEEчтобы получить значение1Lдля достижения simliar доступ-возможность изнутри EL-выражения, я сделал это: (Если есть кодирование-бог - он, надеюсь, простит меня :D )
@Named(value="PERMISSION") public class PERMISSION{ public static class PAGE{ public static final Long SEE = 1L; public static final Long EDIT = 2L; public static final Long DELETE = 4L; ... //EL Wrapper public Long getSEE(){ return PAGE.SEE; } public Long getEDIT(){ return PAGE.EDIT; } public Long getDELETE(){ return PAGE.DELETE; } } //EL-Wrapper public PAGE getPAGE() { return new PAGE(); } }наконец, El-выражение для доступа к тому же
Longбудет:#{PERMISSION.PAGE.SEE}- равенство для Java и EL-Access. Я знаю, что это из любой конвенции, но она работает отлично.
@Божо уже дал отличный ответ
обычно вы размещаете эти виды констант в объекте конфигурации (который имеет геттеры и сеттеры) в контексте сервлета и получаете к ним доступ с помощью ${applicationScope.конфиг.url}
однако, я чувствую, что пример необходим, поэтому он приносит немного больше ясности и сэкономить чье-то время
@Component public Configuration implements ServletContextAware { private String addressURL = Addresses.URL; // Declare other properties if you need as also add corresponding // getters and setters public String getAddressURL() { return addressURL; } public void setServletContext(ServletContext servletContext) { servletContext.setAttribute("config", this); } }
есть обходной путь, который не совсем то, что вы хотите, но позволяет вам активно почти то же самое с трогательными скриптлетами довольно минимальным способом. Вы можете использовать scriptlet, чтобы поместить значение в переменную JSTL и использовать чистый код JSTL позже на странице.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page import="com.whichever.namespace.Addresses" %> <c:set var="ourUrl" value="<%=Addresses.URL%>"/> <c:if test='${"http://www.google.com" eq ourUrl}'> Google is our URL! </c:if>
Comments