ईएल में स्थिरांक कैसे संदर्भित करें?


106

आप एक JSP पृष्ठ पर EL के साथ एक स्थिरांक का संदर्भ कैसे देते हैं?

मेरा एक इंटरफ़ेस है Addressesजिसमें एक स्थिर नाम है URL। मुझे पता है कि मैं इसे एक सारथी के साथ संदर्भित कर सकता हूं: <%=Addresses.URL%>लेकिन मैं ईएल का उपयोग कैसे कर सकता हूं?

जवाबों:


156

ईएल 3.0 या नया

यदि आप पहले से ही जावा ईई 7 / ईएल 3.0 पर हैं, तो @page importईएल गुंजाइश में वर्ग स्थिरांक भी आयात करेंगे।

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

यह कवर के तहत आयात किया जाएगा ImportHandler#importClass()और के रूप में उपलब्ध होगा ${YourConstants.FOO}

ध्यान दें कि सभी java.lang.*वर्ग पहले से ही आयातित हैं और उपलब्ध हैं जैसे ${Boolean.TRUE}और ${Integer.MAX_VALUE}। इसके लिए केवल हाल के जावा ईई 7 कंटेनर सर्वर की आवश्यकता है क्योंकि शुरुआती संस्करणों में इसमें कीड़े थे। जैसे GlassFish 4.0 और Tomcat 8.0.0-1x विफल रहता है, लेकिन GlassFish 4.1+ और Tomcat 8.0.2x + कार्य करता है। और आपको यह सुनिश्चित करने की आवश्यकता है कि आपके web.xmlसर्वर द्वारा समर्थित नवीनतम सर्वलेट संस्करण के अनुरूप घोषित किया गया है। इस प्रकार, web.xmlजिसके साथ सर्वलेट 2.5 या पुराने के अनुरूप घोषित किया जाता है, सर्वलेट 3.0+ सुविधाओं में से कोई भी काम नहीं करेगा।

यह भी ध्यान दें कि यह सुविधा केवल JSP में उपलब्ध है न कि फेसलेट्स में। जेएसएफ + फेसलेट्स के मामले में, आपका सबसे अच्छा दांव नीचे दिए गए अनुसार ओमनीफेस<o:importConstants> का उपयोग कर रहा है :

<o:importConstants type="com.example.YourConstants" />

या एक ईएल संदर्भ श्रोता जोड़ना जो 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");
            }
        });
    }

}

ईएल 2.2 या उससे अधिक पुराना

यह वह जगह है नहीं ईएल 2.2 और उससे अधिक आयु के संभव। कई विकल्प हैं:

  1. उन्हें Map<String, Object>आप आवेदन के दायरे में रखें। ईएल में, मानचित्र मान सामान्य जावबीन मार्ग द्वारा ${map.key}या उसके द्वारा सुलभ हैं ${map['key.with.dots']}

  2. Unstandard टैगलिब <un:useConstants>का उपयोग ( यहाँ maven2 रेपो ):

    <%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
    <un:useConstants className="com.example.YourConstants" var="constants" />
    

    इस तरह वे सामान्य जावबीन रास्ते से सुलभ हैं ${constants.FOO}

  3. इस लेख के निचले भाग में कहीं के रूप में Javranch के CCC का उपयोग करें ।<ccc:constantsMap>

    <%@ taglib uri="http://bibeault.org/tld/ccc" prefix="ccc" %>
    <ccc:constantsMap className="com.example.YourConstants" var="constants" />
    

    इस तरह वे सामान्य जावबीन तरीके से भी सुलभ हैं ${constants.FOO}

  4. आप JSF2 का उपयोग कर रहे हैं, तो आप इस्तेमाल कर सकते हैं <o:importConstants>की OmniFaces

    <html ... xmlns:o="http://omnifaces.org/ui">
    <o:importConstants type="com.example.YourConstants" />
    

    इस तरह वे सामान्य जावबीन तरीके से भी सुलभ हैं #{YourConstants.FOO}

  5. रैपर क्लास बनाएं जो उन्हें जावबीन-शैली के गेट्टर तरीकों के माध्यम से लौटाता है।

  6. एक कस्टम ईएल रिज़ॉल्वर बनाएं जो पहले एक स्थिर की उपस्थिति को स्कैन करता है और यदि अनुपस्थित है, तो डिफ़ॉल्ट रिज़ॉल्वर पर प्रतिनिधि करें, अन्यथा इसके बजाय निरंतर मान लौटाता है।


4
मुझे यह प्रश्न इसलिए मिला क्योंकि एक स्थिर सूची फ़ील्ड को फ़ॉर्म: विकल्प टैग के साथ उपयोग करने की कोशिश करते समय मुझे वही समस्या हो रही थी। मैं एक गैर-स्थैतिक गेटर जोड़कर काम कर पाने में सक्षम था जो स्थैतिक सूची लौटाता है। यह थोड़ा सा अजीब है, लेकिन हे, यह जेएसपी विकास के लिए है!
स्पाकार्की 21

1
क्या आपके पास जेएसएफ के लिए इसे कॉन्फ़िगर करने का कोई उदाहरण है यदि फलियां वसंत द्वारा प्रबंधित की जाती हैं? अग्रिम में Thx।
लॉगर

2
@ लॉगर: मैं स्प्रिंग नहीं करता।
बालुसक

2
क्या जकार्ता unstandard-taglibपरियोजना अभी भी जीवित है? क्या कोई विकल्प है?
डेविओह

1
क्या इस तकनीक का लाभ उठाने का कोई तरीका है?
निकल्स पीटर

11

निम्नलिखित सामान्य रूप से ईएल पर लागू नहीं होता है, लेकिन केवल स्पेल (स्प्रिंग ईएल) के बजाय (टॉमकैट 7 पर 3.2.2.RELEASE के साथ परीक्षण किया गया)। मुझे लगता है कि यह यहाँ ध्यान देने योग्य है कि अगर कोई व्यक्ति JSP और EL की खोज करता है (लेकिन वसंत के साथ JSP का उपयोग करता है)।

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:eval var="constant" expression="T(com.example.Constants).CONSTANT"/>

9

आप आमतौर पर इस प्रकार के स्थिरांक को एक Configurationवस्तु में (जिसमें गेटर्स और सेटर हैं) सर्वलेट संदर्भ में रखते हैं, और उनके साथ एक्सेस करते हैं${applicationScope.config.url}


जब यह jsp की बात आती है, तो एक नौसिखिए की बिट - आप इसे और अधिक पूरी तरह से समझा सकते हैं?
ताऊ-न्यूट्रिनो

1
@ ताऊ-न्यूट्रिनो: इसका सरल वास्तव में है। urlएक स्ट्रिंग संपत्ति के रूप में एक वर्ग बनाएं , इसे नाम दें Configuration, इसे तुरंत लिखें और urlजो भी आपको पसंद हो उसे सेट करें । इसके बाद उस Configurationऑब्जेक्ट को अंदर सेट करें ServletContext। , जैसे कुछ करो servletContext.setAttribute("config", config)। और वहां तुम जाओ।
आदिल अंसारी

आपके प्रस्तावित समाधान और केवल की विशेषता के रूप में स्थिर जोड़ने में क्या अंतर है ServletContext? क्या यह सिर्फ इतना है कि आप स्थिरांक को बड़े करीने से वर्गीकृत कर सकते हैं? जैसे: applicationScope.config.urlबनाम applicationScope.url
वेउव

7

आप नहीं कर सकते। यह जावा बीन सम्मेलन का अनुसरण करता है। तो आपके पास इसके लिए एक गेट्टर होना चाहिए।


5

EL में स्थिर गुण सुलभ नहीं हैं। मैं जिस वर्कअराउंड का उपयोग करता है वह एक गैर-स्थिर वैरिएबल बनाने के लिए है जो खुद को स्थिर मूल्य प्रदान करता है।

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

मैं गटर और सेटर उत्पन्न करने के लिए लोबोक का उपयोग करता हूं ताकि यह बहुत अच्छी तरह से हो। आपका ईएल इस तरह दिखता है:

${bean.manager_role}

Http://www.ninthavenue.com.au/java-static-constants-in-jsp-and-jsf-el पर पूरा कोड


5

मैंने इसे लागू किया:

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

अगले चरण में इस वर्ग का उदाहरण सर्वलर कोटेक्स्ट में रखें

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 में श्रोता जोड़ें

<listener>
    <listener-class>com.example.ApplicationInitializer</listener-class>
</listener>

jsp में पहुंच

${Constants.PAGE_SIZE}

4

मैं शुरुआत में ही अपने jsp में निरंतरता को परिभाषित कर रहा हूं:

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

मैं अपने JSP में मुख्य टैगलिब शामिल करता हूं:

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

फिर, मैं निम्नलिखित कथन द्वारा ईएल को निरंतर उपलब्ध कराता हूं:

<c:set var="URI" value="<%=URI%>"></c:set>

अब, मैं इसे बाद में उपयोग कर सकता हूं। यहां एक उदाहरण है, जहां मान सिर्फ डीबगिंग उद्देश्यों के लिए HTML टिप्पणी के रूप में लिखा गया है:

<!-- ${URI} -->

अपनी निरंतर कक्षा के साथ, आप बस अपनी कक्षा को आयात कर सकते हैं और स्थिरांक को स्थानीय चर में निर्दिष्ट कर सकते हैं। मुझे पता है कि मेरा जवाब एक तरह का त्वरित हैक है, लेकिन सवाल तब भी उठता है जब कोई व्यक्ति सीधे JSP में परिभाषित करना चाहता है।


1
योग्य क्यों नहीं सीधे स्क्रिप्टलेट का उपयोग करें यदि आप ईएल चर को कैसे शुरू करते हैं?
नवीन

शीर्ष पर तीन लाइनें एक गड़बड़ है और फिर JSP के शेष ^ ^ में ईएल को साफ करें।
कोपरपोर

1
@koppoor मुझे ऐसा लगता है। मैं बस उपयोग करने जा रहा हूं <%=URI%>: पी
नवीन

1
मेरे पास एक जगह थी जहां एक प्रत्यक्ष <%=URI%>काम नहीं करता था, लेकिन इस तकनीक ने किया।
21

3

हाँ तुम कर सकते हो। आपको एक कस्टम टैग की आवश्यकता है (यदि आप इसे कहीं और नहीं पा सकते हैं)। मैंने यह किया है:

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" />

सभी सार्वजनिक स्थिर अंतिम चर को उनके जावा नाम द्वारा अनुक्रमित मानचित्र में रखा जाएगा, यदि ऐसा है तो

public static final int MY_FIFTEEN = 15;

तब टैग इसे इंटेगर में लपेट देगा और आप इसे JSP में संदर्भित कर सकते हैं:

<c:if test="${consts['MY_FIFTEEN'] eq 15}">

और आपको गेटर्स नहीं लिखना है!


3

आप ऐसा कर सकते हैं। अनुसरण करने का प्रयास करें

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

टॉमकैट 7 और जावा 6 पर परीक्षण किया गया


3
यह स्पेल जैसा दिखता है, न कि ईएल। क्या मैं गलत हूं? इसके अलावा, यह एक पुराने Tomcat5.5 में काम करेगा?
पाइट्री

2

यहां तक ​​कि इसकी थोड़ी देर जानने के बाद, और यहां तक ​​कि यह जानना थोड़ा हैक है - मैंने वांछित परिणाम प्राप्त करने के लिए निम्नलिखित समाधान का उपयोग किया। यदि आप जावा-नामकरण-सम्मेलनों के प्रेमी हैं, तो मेरी सलाह है कि यहां पढ़ना बंद कर दें ...

इस तरह एक वर्ग होने के कारण, स्थिरांक को परिभाषित करते हुए, एक प्रकार की पदानुक्रम बनाने के लिए खाली कक्षाओं द्वारा समूहीकृत किया जाता है:

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मूल्य को पुनः प्राप्त करने के लिए जावा के भीतर से इस्तेमाल किया जा सकता है1L

ईएल-एक्सप्रेशंस के भीतर से सिमलीयर एक्सेस-संभावना को प्राप्त करने के लिए, मैंने यह किया है: (यदि कोई कोडिंग-ईश्वर है - तो वह उम्मीद है कि मुझे माफ कर सकता है: डी)

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

अंत में, ईएल-एक्सप्रेशन बहुत समान Longहो जाता है: #{PERMISSION.PAGE.SEE}- जावा और ईएल-एक्सेस के लिए समानता। मुझे पता है कि यह किसी भी सम्मेलन से बाहर है, लेकिन यह पूरी तरह से ठीक है।


2

@Bozho ने पहले ही शानदार जवाब दिया

आप सामान्यतया इस प्रकार के स्थिरांक को सर्वलेट संदर्भ में कॉन्फ़िगरेशन ऑब्जेक्ट (जिसमें गेटर्स और सेटर्स होते हैं) में रखते हैं, और उन्हें $ {ApplicationScope.config.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);
    }
}

0

एक वर्कअराउंड है जो वास्तव में आप क्या चाहते हैं, लेकिन आपको बहुत ही न्यूनतम तरीके से स्क्रिप्टिंग को छूने के साथ लगभग सक्रिय नहीं करता है। आप 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>

1
मैं यह नहीं देख रहा हूं कि यह मतदान क्यों किया गया था। यह विकल्प # 3 के रूप में एक ही पैटर्न है: stackoverflow.com/a/16692821/274677
मार्कस जूनियस ब्रूटस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.