JSTL के साथ EL का उपयोग करके Enum मान तक पहुँचें


104

मेरे पास एक Enum है, जिसे स्थिति के रूप में परिभाषित किया गया है:

public enum Status { 

    VALID("valid"), OLD("old");

    private final String val;

    Status(String val) {
        this.val = val;
    }

    public String getStatus() {
        return val;
    }

}

मैं VALIDएक JSTL टैग से मूल्य का उपयोग करना चाहूंगा । विशेष testरूप से <c:when>टैग की विशेषता । उदाहरण के लिए

<c:when test="${dp.status eq Status.VALID">

मुझे यकीन नहीं है कि यह संभव है।

जवाबों:


112

स्ट्रिंग कार्यों के खिलाफ एक सरल तुलना:

<c:when test="${someModel.status == 'OLD'}">

11
स्रोत की आवश्यकता वाले लोगों के लिए: यह "अभिव्यक्ति भाषा विशिष्टता, संस्करण 2.2" के खंड 1.17 में निर्दिष्ट है (उदाहरण के लिए), जो JSR-245 का हिस्सा है ।
मेरिटॉन

4
JavaServer Pages ™ विशिष्टता, संस्करण 2.0 JSP.2.3.5.7 में कहता है: "• यदि A या B स्ट्रिंग A और B दोनों को
ज़ोर से मार रहा है

11
लेकिन आपने एनम होने का फायदा ढीला कर दिया: अगर एक दिन एनम बदल जाता है तो इससे आपको गलतफहमी हो सकती है। आमतौर पर, अगर मैं खुद को एक एनम बदलते हुए पाता हूं, तो मैं बहुत सुरक्षित महसूस करता हूं, और शायद मुझे उस दृश्य में स्ट्रिंग-टू-
एनम

1
क्या यह एनम के तने के खिलाफ तुलना है? इसलिए यदि आप toString (जैसे आप एक अनुकूल प्रदर्शन नाम चाहते हैं) को ओवरराइड करते हैं, तो आपको यह सुनिश्चित करने की आवश्यकता है कि आप उस मूल्य को भी बदलते हैं जिसका मिलान किया जा रहा है।
रूपर्ट मैडेन-एबॉट

1
FWIW, आज मेरे जावा 8 पर (आईबीएम जावा वेबस्फीयर के लिए, यदि यह मायने रखता है), तो यह काम नहीं करता है। यह केवल तभी काम करता है जब स्ट्रिंग मान के खिलाफ तुलना की जाती है, जो यहां "पुराना" कम मामला होगा
dbreaux

54

यदि स्प्रिंग MVC का उपयोग किया जाता है, तो वसंत अभिव्यक्ति भाषा (स्पेल) सहायक हो सकती है:

<spring:eval expression="dp.status == T(com.example.Status).VALID" var="isValid" />
<c:if test="${isValid}">
   isValid
</c:if>

1
ऐसा लगता है कि यह आंतरिक एनम के लिए काम नहीं करता है? इसके कारण: org.springframework.expression.spel.SpelEvaluationException: EL1005E: (स्थिति 0): टाइप 'my.package.model.EngagementRequest.EngagementStatus'
एडी

4
'My.package.model.EngagementRequest $ EngagementStatus' का उपयोग करने का प्रयास करें
जेम्स

इस समाधान के बारे में एक अच्छी बात यह है कि आपको एक त्रुटि संदेश मिलता है यदि आपकी अभिव्यक्ति में कोई गलती है, जो हमेशा साथ नहीं होता है <c:if>और <c:when>(वे चुपचाप विफल होते हैं)।
vegemite4me

41

आपके पास यहां 3 विकल्प हैं, जिनमें से कोई भी सही नहीं है:

  1. आप testविशेषता में एक स्क्रिप्ट का उपयोग कर सकते हैं :

    <c:when test="<%= dp.getStatus() == Status.VALID %>">

    यह एनम का उपयोग करता है, लेकिन यह एक स्क्रिप्टलेट का भी उपयोग करता है, जो जेएसपी 2.0 में "सही तरीका" नहीं है। लेकिन सबसे महत्वपूर्ण बात, यह तब काम नहीं करता है जब आप उसी whenका उपयोग करके एक और शर्त जोड़ना चाहते हैं ${}। और इसका मतलब है कि आपके द्वारा परीक्षण किए जाने वाले सभी चर को एक स्क्रिप्टलेट में घोषित किया जाना है, या अनुरोध में रखा गया है, या सत्र ( फ़ाइलों pageContextमें चर उपलब्ध नहीं है .tag)।

  2. आप स्ट्रिंग के खिलाफ तुलना कर सकते हैं:

    <c:when test="${dp.status == 'VALID'}">

    यह साफ दिखता है, लेकिन आप एक स्ट्रिंग पेश कर रहे हैं, जो एनम मान को डुप्लिकेट करता है और संकलक द्वारा मान्य नहीं किया जा सकता है। इसलिए यदि आप उस मान को एनम से हटा देते हैं या उसका नाम बदल देते हैं, तो आप यह नहीं देखेंगे कि कोड का यह हिस्सा अब उपलब्ध नहीं है। आपको मूल रूप से प्रत्येक बार कोड के माध्यम से एक खोज / प्रतिस्थापित करना होगा।

  3. आप पृष्ठ संदर्भ में उपयोग किए जाने वाले प्रत्येक enum मान जोड़ सकते हैं:

    <c:set var="VALID" value="<%=Status.VALID%>"/>

    और फिर आप यह कर सकते हैं:

    <c:when test="${dp.status == VALID}">

मैं अंतिम विकल्प (3) पसंद करता हूं, भले ही यह एक स्क्रिप्टलेट का उपयोग करता है। ऐसा इसलिए है क्योंकि जब आप मान सेट करते हैं तो यह इसका उपयोग करता है बाद में आप इसे अन्य ईएल स्थितियों के साथ अधिक जटिल ईएल अभिव्यक्तियों में उपयोग कर सकते हैं। विकल्प (1) में रहते हुए आप testएक whenटैग की विशेषता में एक स्क्रिप्ट और एक ईएल अभिव्यक्ति का उपयोग नहीं कर सकते ।


1
विकल्प 2 के बारे में, संकलक इसे सत्यापित नहीं कर सकता है, लेकिन रनटाइम पर स्ट्रिंग को एक एनम में परिवर्तित किया Enum.valueOf(Class<T> enumType, String name)जाएगा, जिसके उपयोग से ट्रिगर होगा ELExceptionयदि एनम के पास उस नाम के साथ कोई स्थिरांक नहीं है। अभिव्यक्ति हमेशा झूठी नहीं होगी।
रिबूट

23

तो मेरी समस्या को पूरी तरह से हल करने के लिए मुझे निम्नलिखित करने की आवश्यकता है:

<% pageContext.setAttribute("old", Status.OLD); %>

तब मैं कर पाया:

<c:when test="${someModel.status == old}"/>...</c:when>

जो उम्मीद के मुताबिक काम किया।


12
स्क्रिप्ट का उपयोग करना खराब शैली है।
यूजीन रेटुनस्की

13

यहाँ दो और संभावनाएँ हैं:

जेएसपी ईएल 3.0 लगातार

जब तक आप ईएल के कम से कम संस्करण 3.0 का उपयोग कर रहे हैं, तब तक आप अपने पेज में स्थिरांक आयात कर सकते हैं:

<%@ page import="org.example.Status" %>
<c:when test="${dp.status eq Status.VALID}">

हालाँकि, कुछ IDE को यह अभी तक समझ में नहीं आया है (उदाहरण के लिए IntelliJ ) ताकि आपको कोई चेतावनी न मिले यदि आप एक टाइपो बनाते हैं, रनटाइम तक।

उचित आईडीई समर्थन मिलने के बाद यह मेरा पसंदीदा तरीका होगा।

हेल्पर के तरीके

तुम बस अपने enum में getters जोड़ सकते हैं।

public enum Status { 
  VALID("valid"), OLD("old");

  private final String val;

  Status(String val) {
    this.val = val;
  }

  public String getStatus() {
    return val;
  }

  public boolean isValid() {
    return this == VALID;
  }

  public boolean isOld() {
    return this == OLD;
  }
}

फिर अपने JSP में:

<c:when test="${dp.status.valid}">

यह सभी IDE में समर्थित है और यदि आप अभी तक EL 3.0 का उपयोग नहीं कर सकते हैं तो भी यह काम करेगा। इस समय मैं यही कर रहा हूं क्योंकि यह सभी तर्क को मेरी दुश्मनी में लिपटा रखता है।

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

<c:when test="${not empty db.status and dp.status.valid}">

मुझे लगता है कि यह विधि उन लोगों के लिए बेहतर है जहां आपने JSP में एक मध्यस्थ मूल्य निर्धारित किया है क्योंकि आपको प्रत्येक पृष्ठ पर ऐसा करना है जहां आपको एनम का उपयोग करने की आवश्यकता है। हालांकि, इस समाधान के साथ आपको केवल एक बार गेटर घोषित करने की आवश्यकता है।


2
"जेएसपी ईएल 3.0 कॉन्स्टेंट" भाग को स्वीकृत उत्तर होना चाहिए क्योंकि यह अंतर्निहित कार्यक्षमता का उपयोग करके आवश्यक परिणाम प्राप्त करने का मानक तरीका है। एक साइड नोट पर, InteliJ IDEA (कम से कम अंतिम संस्करण 2017.2.4) बॉक्स से बाहर का समर्थन करता है और जब आप टाइप करते हैं तो उपलब्ध स्थिरांक की सूची दिखाते हैं, ${MyEnum.}डॉट के ठीक बाद कैरेट डालते हैं और Ctrl+Spaceसुझाव दिखाने के लिए दबाते हैं।
izogfif

[ अद्यतन ] इंटेलीज आईडीईए की तरह लगता है कि इस उत्तर में उल्लिखित समस्या पहले से ही तय है।
informatik01

10

इस उद्देश्य के लिए मैं निम्नलिखित कार्य करता हूं:

<c:set var="abc">
    <%=Status.OLD.getStatus()%>
</c:set>

<c:if test="${someVariable == abc}">
    ....
</c:if>

यह बदसूरत लग रहा है, लेकिन काम करता है!


3

मेरे पास कोर्नेल के प्रश्न का उत्तर नहीं है, लेकिन मैं अन्य स्क्रिप्ट उदाहरणों के बारे में टिप्पणी करता हूं। अधिकांश अभिव्यक्ति ट्रस्ट पर स्पष्ट रूप से विश्वास करते हैं toString(), लेकिन Enum.valueOf()एक मूल्य की अपेक्षा करता है जो Enum.name()संपत्ति से आता है / मेल खाता है । इसलिए एक का उपयोग करना चाहिए:

<% pageContext.setAttribute("Status_OLD", Status.OLD.name()); %>
...
<c:when test="${someModel.status == Status_OLD}"/>...</c:when>

2

एनम की तरह एक विधि जोड़ें:

public String getString() {
    return this.name();
}

उदाहरण के लिए

public enum MyEnum {
    VALUE_1,
    VALUE_2;
    public String getString() {
        return this.name();
    }
}

तो आप का उपयोग कर सकते हैं:

<c:if test="${myObject.myEnumProperty.string eq 'VALUE_2'}">...</c:if>

1

एमवीसी ढांचे का उपयोग करते समय मैंने निम्नलिखित को अपने नियंत्रक में रखा।

request.setAttribute(RequestParameterNamesEnum.INBOX_ACTION.name(), RequestParameterNamesEnum.INBOX_ACTION.name());

यह मुझे अपने JSP पेज में निम्नलिखित का उपयोग करने की अनुमति देता है।

<script> var url = 'http://www.nowhere.com/?${INBOX_ACTION}=' + someValue;</script>

यह आपकी तुलना में भी इस्तेमाल किया जा सकता है

<c:when test="${someModel.action == INBOX_ACTION}">

जिसे मैं एक स्ट्रिंग शाब्दिक में रखना पसंद करता हूं।


1
<%@ page import="com.example.Status" %>

1. ${dp.status eq Title.VALID.getStatus()}
2. ${dp.status eq Title.VALID}
3. ${dp.status eq Title.VALID.toString()}
  • आयात को सबसे ऊपर , JSP पेज हेडर में रखें
  • यदि आप गेटस्टस विधि के साथ काम करना चाहते हैं , तो # 1 का उपयोग करें
  • यदि आप एनम तत्व के साथ काम करना चाहते हैं , तो # 2 या # 3 का उपयोग करें
  • आप eq के बजाय == का उपयोग कर सकते हैं

-1

मैं आमतौर पर जावा कोड को jsps / टैग फ़ाइलों में मिलाने के लिए इसे बुरा अभ्यास मानता हूं। 'Eq' के प्रयोग से चाल चलनी चाहिए:

<c:if test="${dp.Status eq 'OLD'}">
  ...
</c:if>

3
तो इसके ==बजाय उपयोग करना एक बुरा अभ्यास है eq? वे दोनों बिल्कुल एक ही करते हैं, इसलिए "चाल" का कोई मतलब नहीं है।
बालुसक

बेशक, मैं eq बनाम == के उपयोग के बारे में एक बयान नहीं दे रहा था। इस प्रश्न के कई जवाबों में java कोड को jsp या टैग फ़ाइलों में सम्मिलित करना शामिल है जो एक बैसाखी हो सकती है। मैं Java कोड में व्यावसायिक तर्क रखने का पक्ष लेता हूं (जहां यह आसानी से और पूरी तरह से जांच की जाने वाली इकाई हो सकती है) JSP में प्रदर्शित तर्क से अलग।
एलाटांटे

7
मेरे लिए यह आपके जेएसपी में जादू के तार डालने के लिए एक समान रूप से बुरा अभ्यास लगता है जिसे कंपाइलर द्वारा जांच नहीं किया जा सकता है जब आप अपने एनम को रिफलेक्टर करना चाहते हैं। ऐसा लगता है कि दोनों तरफ इसका कोई अच्छा हल नहीं है।
लाइल

-1

मैं इसे इस तरह से करता हूं जब उपयोग करने के लिए कई बिंदु होते हैं ...

public enum Status { 

    VALID("valid"), OLD("old");

    private final String val;

    Status(String val) {
        this.val = val;
    }

    public String getStatus() {
        return val;
    }

    public static void setRequestAttributes(HttpServletRequest request) {
        Map<String,String> vals = new HashMap<String,String>();
        for (Status val : Status.values()) {
            vals.put(val.name(), val.value);
        }
        request.setAttribute("Status", vals);
    }

}

JSP

<%@ page import="...Status" %>
<% Status.setRequestAttributes(request) %>

<c:when test="${dp.status eq Status.VALID}">
...

-2

जावा क्लास में:

    public class EnumTest{
    //Other property link
    private String name;
    ....

        public enum Status {
                ACTIVE,NEWLINK, BROADCASTED, PENDING, CLICKED, VERIFIED, AWARDED, INACTIVE, EXPIRED, DELETED_BY_ADMIN;
            }

        private Status statusobj ;

    //Getter and Setters
}

तो अब POJO और enum obj बनाया गया है। अब EnumTest आप सर्वलेट या कंट्रोलर क्लास सेशन में प्रयोग करके सत्र ऑब्जेक्ट में सेट करेंगे ।setAttribute ("enumTest", EnumTest);

JSP पेज में

<c:if test="${enumTest.statusobj == 'ACTIVE'}">

//TRUE??? THEN PROCESS SOME LOGIC
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.