Bir JSP sayfasında EL sabitlerine nasıl başvurursunuz?
Addresses
Sabit isimli bir arayüzüm var URL
. Bunu bir komut dosyasıyla şu şekilde referans gösterebileceğimi biliyorum: <%=Addresses.URL%>
ama bunu EL kullanarak nasıl yapabilirim?
Bir JSP sayfasında EL sabitlerine nasıl başvurursunuz?
Addresses
Sabit isimli bir arayüzüm var URL
. Bunu bir komut dosyasıyla şu şekilde referans gösterebileceğimi biliyorum: <%=Addresses.URL%>
ama bunu EL kullanarak nasıl yapabilirim?
Yanıtlar:
Zaten Java EE 7 / EL 3.0 kullanıyorsanız, @page import
sınıf sabitlerini de EL kapsamına aktaracaktır.
<%@ page import="com.example.YourConstants" %>
Bu kapakların altına aktarılacak ImportHandler#importClass()
ve olarak satışa sunulacaktır ${YourConstants.FOO}
.
Tüm java.lang.*
sınıfların zaten dolaylı olarak içe aktarıldığını ve böyle ${Boolean.TRUE}
ve gibi kullanılabilir olduğunu unutmayın ${Integer.MAX_VALUE}
. Bu, yalnızca daha yeni bir Java EE 7 kapsayıcı sunucusu gerektirir, çünkü önceki sürümlerde hatalar vardır. Örneğin, GlassFish 4.0 ve Tomcat 8.0.0-1x başarısız olur, ancak GlassFish 4.1+ ve Tomcat 8.0.2x + çalışır. Ayrıca web.xml
, sunucunuzun sunucu tarafından desteklenen en son sunucu uygulaması sürümüne uygun olduğunun beyan edildiğinden kesinlikle emin olmanız gerekir . Dolayısıyla, web.xml
Servlet 2.5 veya daha eski bir sürümle uyumlu olduğu bildirilen bir ile, Servlet 3.0+ özelliklerinin hiçbiri çalışmayacaktır.
Ayrıca bu özelliğin sadece JSP'de mevcut olduğunu ve Facelets'te bulunmadığını unutmayın. JSF + Facelets durumunda, en iyi bahsiniz aşağıdaki gibi OmniFaces<o:importConstants>
kullanmaktır :
<o:importConstants type="com.example.YourConstants" />
Veya ImportHandler#importClass()
aşağıdaki gibi çağıran bir EL bağlam dinleyicisi eklemek :
@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");
}
});
}
}
Bu değil EL 2.2 ve daha eski mümkün. Birkaç alternatif var:
Bunları Map<String, Object>
uygulama kapsamına koyduğunuz bir yere koyun. EL'de, harita değerlerine normal Javabean yoluyla ${map.key}
veya ile erişilebilir ${map['key.with.dots']}
.
Kullanım <un:useConstants>
ait Unstandard taglib (Maven2 repo burada ):
<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
<un:useConstants className="com.example.YourConstants" var="constants" />
Bu şekilde, normal Javabean yoluyla erişilebilirler ${constants.FOO}
.
Kullanım Javaranch en CCC <ccc:constantsMap>
altındaki desribed yerde olarak bu makalede .
<%@ taglib uri="http://bibeault.org/tld/ccc" prefix="ccc" %>
<ccc:constantsMap className="com.example.YourConstants" var="constants" />
Bu şekilde normal Javabean yoluyla da erişilebilirler ${constants.FOO}
.
JSF2 kullanıyorsanız <o:importConstants>
, OmniFaces'i kullanabilirsiniz .
<html ... xmlns:o="http://omnifaces.org/ui">
<o:importConstants type="com.example.YourConstants" />
Bu şekilde normal Javabean yoluyla da erişilebilirler #{YourConstants.FOO}
.
Javabean tarzı alıcı yöntemleriyle onları döndüren bir sarmalayıcı sınıfı oluşturun.
Önce bir sabitin varlığını tarayan ve yoksa, varsayılan çözümleyiciye delege eden, aksi takdirde bunun yerine sabit değeri döndüren özel bir EL çözümleyici oluşturun.
unstandard-taglib
projesi hala yaşıyor mu? alternatif var mı
Aşağıdakiler genel olarak EL için geçerli değildir, bunun yerine yalnızca SpEL (Spring EL) için geçerlidir (Tomcat 7'de 3.2.2.RELEASE ile test edilmiştir). Birisinin JSP ve EL için arama yapması durumunda (ancak Spring ile JSP kullanması durumunda) burada bahsetmeye değer olduğunu düşünüyorum.
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:eval var="constant" expression="T(com.example.Constants).CONSTANT"/>
Bu tür sabitleri genellikle Configuration
sunucu uygulaması bağlamındaki bir nesneye (alıcıları ve ayarlayıcıları olan) yerleştirirsiniz ve bunlara${applicationScope.config.url}
url
String özelliğine sahip bir sınıf oluşturun , adlandırın Configuration
, örnekleyin ve istediğiniz url
şekilde ayarlayın . Bundan sonra o Configuration
nesneyi yerleştirin ServletContext
. , Gibi bir şey yapın servletContext.setAttribute("config", config)
. Ve işte gidiyorsun.
ServletContext
? Sadece sabitleri daha düzgün bir şekilde sınıflandırabilmeniz için mi? örneğin: applicationScope.config.url
vs applicationScope.url
.
Yapamazsın. Java Bean kuralını izler. Yani bunun için bir alıcıya sahip olmalısın.
EL'de statik özelliklere erişilemez. Kullandığım geçici çözüm, kendisini statik değere atayan statik olmayan bir değişken oluşturmaktır.
public final static String MANAGER_ROLE = 'manager';
public String manager_role = MANAGER_ROLE;
Alıcı ve ayarlayıcıyı üretmek için lombok kullanıyorum, bu oldukça iyi. EL'niz şuna benzer:
${bean.manager_role}
Tam kod http://www.ninthavenue.com.au/java-static-constants-in-jsp-and-jsf-el adresinde
Ben şöyle uyguladım:
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;
}
}
Sonraki adım bu sınıfın örneğini servlerContext'e koy
public class ApplicationInitializer implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute("Constants", new JspConstants());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
web.xml'ye dinleyici ekle
<listener>
<listener-class>com.example.ApplicationInitializer</listener-class>
</listener>
jsp'de erişim
${Constants.PAGE_SIZE}
En başında jsp'mde bir sabit tanımlıyorum:
<%final String URI = "http://www.example.com/";%>
Çekirdek taglib'i JSP'me dahil ediyorum:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
Ardından, aşağıdaki ifadeyi kullanarak sabiti EL için kullanılabilir hale getiriyorum:
<c:set var="URI" value="<%=URI%>"></c:set>
Şimdi, daha sonra kullanabilirim. Burada, değerin yalnızca hata ayıklama amacıyla HTML açıklaması olarak yazıldığı bir örnek:
<!-- ${URI} -->
Sabit sınıfınızla, sınıfınızı içe aktarabilir ve sabitleri yerel değişkenlere atayabilirsiniz. Cevabımın bir tür hızlı hack olduğunu biliyorum, ancak soru sabitleri doğrudan JSP'de tanımlamak istediğinde de artıyor.
<%=URI%>
: P
<%=URI%>
çalışmayan bir yerim vardı ama bu teknik işe yaradı.
Evet yapabilirsin. Özel bir etikete ihtiyacınız var (eğer başka bir yerde bulamazsanız). Bunu yaptım:
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;
}
}
ve etiketin adı:
<yourLib:constMap path="path.to.your.constantClass" var="consts" />
Tüm genel statik son değişkenler, Java adlarına göre indekslenmiş bir Haritaya yerleştirilecektir.
public static final int MY_FIFTEEN = 15;
sonra etiket bunu bir Tamsayı olarak sarar ve bir JSP'de buna referans verebilirsiniz:
<c:if test="${consts['MY_FIFTEEN'] eq 15}">
ve alıcılar yazmanıza gerek yok!
Yapabilirsin. Takip yolunu dene
#{T(com.example.Addresses).URL}
TomCat 7 ve java6'da test edildi
Biraz geç olduğunu ve hatta bunun küçük bir hack olduğunu bilmek bile - istenen sonucu elde etmek için aşağıdaki çözümü kullandım. Java Adlandırma Konvansiyonlarını seviyorsanız, tavsiyem burada okumayı bırakmanızdır ...
Bunun gibi bir sınıfa sahip olmak, Sabitleri tanımlamak, bir tür hiyerarşi yaratmak için boş sınıflara göre gruplandırılmak:
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;
...
}
}
PERMISSION.PAGE.SEE
değeri almak için java içinden kullanılabilir1L
EL-İfadeleri içinden benzer bir erişim olasılığı elde etmek için şunu yaptım: (Bir kodlama tanrısı varsa - umarım beni affedebilir: 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();
}
}
son olarak, aynısına erişmek için EL-İfadesi şu Long
hale gelir: #{PERMISSION.PAGE.SEE}
- Java ve EL-Access için eşitlik. Bunun herhangi bir konvansiyonun dışında olduğunu biliyorum, ama gayet iyi çalışıyor.
@Bozho zaten harika bir cevap verdi
Bu tür sabitleri genellikle sunucu uygulaması bağlamındaki bir Yapılandırma nesnesine (alıcıları ve ayarlayıcıları olan) yerleştirir ve bunlara $ {applicationScope.config.url} ile erişirsiniz.
Bununla birlikte, bir örneğe ihtiyaç olduğunu hissediyorum, bu yüzden biraz daha netlik getiriyor ve birine zaman ayırıyor
@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);
}
}
Tam olarak istediğiniz şey olmayan, ancak komut dosyalarına dokunarak neredeyse aynı şekilde oldukça minimal bir şekilde aktif olmanıza izin veren bir geçici çözüm var. Bir JSTL değişkenine değer eklemek için betik uygulamasını kullanabilir ve sayfanın ilerleyen kısımlarında temiz JSTL kodunu kullanabilirsiniz.
<%@ 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>