Como fazer referência a constantes no EL?

Como você faz referência a constantes com EL em uma página JSP?

Eu tenho uma interface Addresses com uma constante nomeada URL . Eu sei que posso referenciá-lo com um scriplet indo em: , mas como faço isso usando o EL?

EL 3.0 ou mais recente

Se você já estiver no Java EE 7 / EL 3.0, a @page import também importará constantes de class no escopo EL.

 < %@ page import="com.example.YourConstants" %> 

Isso será importado via ImportHandler#importClass() e estará disponível como ${YourConstants.FOO} .

Observe que todas as classs java.lang.* Já estão implicitamente importadas e disponíveis, como ${Boolean.TRUE} e ${Integer.MAX_VALUE} . Isso requer apenas um servidor de contêiner Java EE 7 mais recente, já que versões anteriores continham bugs. Por exemplo, o GlassFish 4.0 e o Tomcat 8.0.0-1x falham, mas o GlassFish 4.1+ e o Tomcat 8.0.2x + funcionam.

Esse recurso está disponível apenas no JSP e não no Facelets. No caso do JSF + Facelets, sua melhor aposta é usar o OmniFaces como abaixo:

  

Ou adicionando um ouvinte de contexto EL que chama ImportHandler#importClass() como abaixo:

 @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 ou mais

Isso não é possível no EL 2.2 e mais antigo. Existem várias alternativas:

  1. Coloque-os em um Map que você coloca no escopo do aplicativo. Em EL, os valores do mapa são acessíveis da maneira usual do Java por ${map.key} ou ${map['key.with.dots']} .

  2. Use do taglib Unstandard (maven2 repo aqui ):

     < %@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>  

    Desta forma, eles estão acessíveis a maneira usual do Java por ${constants.FOO} .

  3. Use CCC Javaranch como desribed algures no final deste artigo .

     < %@ taglib uri="http://bibeault.org/tld/ccc" prefix="ccc" %>  

    Dessa forma, eles também podem acessar a forma habitual do JavaBean por ${constants.FOO} .

  4. Se você estiver usando o JSF2, poderá usar do OmniFaces .

       

    Dessa forma, eles também podem acessar a maneira habitual do #{YourConstants.FOO} .

  5. Crie uma class de wrapper que os retorne por meio dos methods getter no estilo do Javabean.

  6. Crie um solucionador EL customizado que primeiro verifique a presença de uma constante e, se ausente, em seguida, delegue para o resolvedor padrão, caso contrário, retorna o valor constante.

Você geralmente coloca esses tipos de constantes em um object Configuration (que possui getters e setters) no contexto do servlet e os acessa com ${applicationScope.config.url}

O seguinte não se aplica a EL em geral, mas sim a SpEL (Spring EL) somente (testado com 3.2.2.RELEASE no Tomcat 7). Eu acho que vale a pena mencionar aqui no caso de alguém pesquisar por JSP e EL (mas usa JSP com Spring).

 < %@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>  

Você não pode. Segue a convenção do Java Bean. Então você deve ter um getter para isso.

Propriedades estáticas não são acessíveis no EL. A solução alternativa que uso é criar uma variável não estática que se atribui ao valor estático.

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

Eu uso o lombok para gerar o getter e o setter, então é muito bom. Seu EL é assim:

 ${bean.manager_role} 

Código completo em http://www.ninthavenue.com.au/java-static-constants-in-jsp-and-jsf-el

Eu implementei como:

 public interface Constants{ Integer PAGE_SIZE = 20; } 

 public class JspConstants extends HashMap { 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; } } 

Próximo passo coloque a instância desta class no servlerContext

 public class ApplicationInitializer implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { sce.getServletContext().setAttribute("Constants", new JspConstants()); } @Override public void contextDestroyed(ServletContextEvent sce) { } } 

adicionar ouvinte ao web.xml

  com.example.ApplicationInitializer  

access em jsp

 ${Constants.PAGE_SIZE} 

Sim você pode. Você precisa de uma tag personalizada (se não puder encontrá-la em outro lugar). Eu fiz isso:

 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 constMap = new TreeMap (); 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; } } 

e a tag é chamada:

  

Todas as variables ​​finais estáticas públicas serão colocadas em um Mapa indexado por seu nome Java, portanto, se

 public static final int MY_FIFTEEN = 15; 

então a tag irá envolver isso em um Integer e você pode referenciá-lo em um JSP:

  

e você não precisa escrever getters!

Você pode. Tente seguir o caminho

  #{T(com.example.Addresses).URL} 

Testado no TomCat 7 e no java6

Estou definindo uma constante no meu jsp logo no começo:

 < %final String URI = "http://www.example.com/";%> 

Eu incluo o taglib principal no meu JSP:

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

Então, eu faço a constante disponível para EL, seguindo a seguinte declaração:

  

Agora posso usá-lo mais tarde. Aqui está um exemplo, onde o valor é apenas escrito como comentário HTML para fins de debugging:

  

Com sua class constante, você pode apenas importar sua class e atribuir as constantes a variables ​​locais. Eu sei que minha resposta é uma espécie de hack rápido, mas a questão também aumenta quando se quer definir constantes diretamente no JSP.

Mesmo sabendo que é um pouco tarde, e mesmo sabendo que isso é um pouco hack – usei a seguinte solução para alcançar o resultado desejado. Se você é um amante de convenções de nomenclatura Java, meu conselho é parar de ler aqui …

Tendo uma class como essa, definindo constantes, agrupadas por classs vazias para criar um tipo de hierarquia:

 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; ... } } 

pode ser usado de dentro de java como PERMISSION.PAGE.SEE para recuperar o valor 1L

Para conseguir uma possibilidade de access semelhante a partir do EL-Expressions, eu fiz isso: (Se existe um deus codificador – ele esperançosamente poderia me perdoar: 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(); } } 

finalmente, a EL-Expression para acessar o mesmo Long se torna: #{PERMISSION.PAGE.SEE} – igualdade para Java e EL-Access. Eu sei que isso está fora de qualquer convenção, mas funciona perfeitamente bem.

@Bozho já forneceu uma ótima resposta

Você geralmente coloca esses tipos de constantes em um object Configuration (que possui getters e setters) no contexto do servlet e os acessa com $ {applicationScope.config.url}

No entanto, sinto que um exemplo é necessário, por isso traz um pouco mais de clareza e poupa o tempo de alguém

 @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); } } 

Há uma solução alternativa que não é exatamente o que você quer, mas permite que você ative quase o mesmo com tocar os scriptlets de maneira mínima. Você pode usar o scriptlet para colocar o valor em uma variável JSTL e usar o código JSTL limpo posteriormente na página.

 < %@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> < %@ page import="com.whichever.namespace.Addresses" %>   Google is our URL!