জেএসটিএল সহ EL ব্যবহার করে এনাম মান অ্যাক্সেস করুন


104

আমার স্ট্যাটাস নামক একটি এনাম রয়েছে যা এরূপ হিসাবে সংজ্ঞায়িত হয়:

public enum Status { 

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

    private final String val;

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

    public String getStatus() {
        return val;
    }

}

আমি VALIDএকটি জেএসটিএল ট্যাগ থেকে মানটি অ্যাক্সেস করতে চাই । বিশেষত ট্যাগটির testবৈশিষ্ট্য <c:when>। যেমন

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

আমি নিশ্চিত না এটি সম্ভব কিনা।

উত্তর:


112

স্ট্রিংয়ের বিরুদ্ধে একটি সাধারণ তুলনা কাজ করে:

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

11
যাদের উত্সের প্রয়োজন তাদের জন্য: এটি "এক্সপ্রেশন ল্যাঙ্গুয়েজ স্পেসিফিকেশন, সংস্করণ ২.২" এর ১.১ । বিভাগে সুনির্দিষ্ট (উদাহরণস্বরূপ), যা জেএসআর -৪৪৫ এর অংশ ।
মেরিটন

4
জাভা সার্ভার পৃষ্ঠাগুলি ™ স্পেসিফিকেশন, সংস্করণ ২.০ জেএসপি ২.৩.৩. says-তে বলেছেন: "A যদি A বা B স্ট্রিং এ এবং বি উভয়কে স্ট্রিংকে চাপিয়ে দেয় তবে বিন্যাসের সাথে তুলনা করুন"
রোল্যান্ড ইলিগ

11
তবে আপনি এনাম থাকার সুবিধাটি ছেড়ে দিয়েছেন: যদি এনাম একদিন পরিবর্তিত হয় তবে এটি জটিল ভুল বোঝাবুঝির কারণ হতে পারে। সাধারণত, যদি আমি নিজেকে একটি এনাম পরিবর্তন করতে দেখি তবে আমি বেশ নিরাপদ বোধ করি এবং সম্ভবত আমি সেই দৃশ্যে সেই স্ট্রিং-টু-এনাম-রেফারেন্সটি মনে রাখব না ...
সত্যই সুন্দরভাবে

1
এটি কি এনামের টস্ট্রিংয়ের সাথে তুলনা করে? সুতরাং আপনি যদি টসস্ট্রিংকে ওভাররাইড করেন (যেমন আপনি একটি বন্ধুত্বপূর্ণ প্রদর্শনের নাম চান), তবে আপনাকে অবশ্যই নিশ্চিত করতে হবে যে আপনি যে মানটির সাথে মিলে যাচ্ছে তারও পরিবর্তন করেছেন।
রুপার্ট ম্যাডেন-অ্যাবট

1
এফডব্লিউআইডাব্লু, আজ আমার জাভা 8 এ (ওয়েবস্পিয়ারের জন্য আইবিএম জাভা, যদি বিষয়টি বিবেচনা করে) তবে এটি কার্যকর বলে মনে হচ্ছে না। স্ট্রিং মানটির সাথে তুলনা করলে এটি কেবল কাজ করে বলে মনে হচ্ছে, যা এখানে নিম্নতর "পুরানো" হবে
ডাব্রুউক্স

54

যদি স্প্রিং এমভিসি ব্যবহার করে তবে স্প্রিং এক্সপ্রেশন ল্যাঙ্গুয়েজ (স্পেল) সহায়ক হতে পারে:

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

1
মনে হচ্ছে এটি অভ্যন্তরীণ এনামগুলিতে কাজ করে না? এর দ্বারা তৈরি: org.springframework.expression.spel.Selel মূল্যায়ন ধারণা: EL1005E: (পোস্ট 0): প্রকারটি 'my.package.model.EgeagementRequest.EngagementStatus' খুঁজে পাওয়া যায় নি
এডি

4
'My.package.model.EgeagementRequest age EngagementStatus' ব্যবহার করার চেষ্টা করুন
জেমস

এই সমাধানটির একটি ভাল বিষয় হ'ল আপনার অভিব্যক্তিতে কোনও ভুল থাকলে আপনি একটি ত্রুটি বার্তা পান যা সর্বদা ঘটে না <c:if>এবং <c:when>(তারা চুপ করে ব্যর্থ হয়)।
vegemite4me

41

আপনার এখানে 3 টি পছন্দ রয়েছে যার মধ্যে কোনওটিই নিখুঁত নয়:

  1. আপনি testবৈশিষ্ট্যে একটি স্ক্রিপ্টলেট ব্যবহার করতে পারেন :

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

    এটি এনাম ব্যবহার করে তবে এটি স্ক্রিপ্টলেটও ব্যবহার করে যা জেএসপি ২.০ এ "সঠিক উপায়" নয়। তবে সবচেয়ে গুরুত্বপূর্ণ, আপনি যখন অন্যটি whenব্যবহার করে একই শর্ত যুক্ত করতে চান তখন এটি কাজ করে না ${}। এবং এর অর্থ হল আপনি যে সমস্ত ভেরিয়েবল পরীক্ষা করতে চান তা স্ক্রিপ্টলেটে ঘোষণা করতে হবে, বা অনুরোধে রাখতে হবে, বা সেশনে ( pageContextভেরিয়েবল .tagফাইলগুলিতে উপলব্ধ নেই )।

  2. আপনি স্ট্রিংয়ের সাথে তুলনা করতে পারেন:

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

    এটি দেখতে দেখতে পরিষ্কার দেখাচ্ছে তবে আপনি এমন একটি স্ট্রিং প্রবর্তন করছেন যা এনাম মানটিকে সদৃশ করে এবং সংকলক দ্বারা বৈধ হওয়া যায় না। সুতরাং আপনি যদি এনাম থেকে সেই মানটি সরিয়ে ফেলেন বা নাম পরিবর্তন করেন, আপনি দেখতে পাবেন না কোডের এই অংশটি আর অ্যাক্সেসযোগ্য নয়। আপনাকে মূলত প্রতিটি সময় কোডের মাধ্যমে একটি অনুসন্ধান / প্রতিস্থাপন করতে হবে।

  3. আপনি পৃষ্ঠা প্রসঙ্গে আপনার ব্যবহৃত প্রতিটি এনাম মান যুক্ত করতে পারেন:

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

    এবং তারপরে আপনি এটি করতে পারেন:

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

আমি শেষ বিকল্পটি পছন্দ করি (3), যদিও এটি স্ক্রিলেটলেটও ব্যবহার করে। এটি কেবলমাত্র যখন আপনি মান সেট করেন তখন এটি ব্যবহার করে। পরে আপনি অন্যান্য EL শর্তগুলির সাথে একত্রে আরও জটিল EL এক্সপ্রেশনগুলিতে এটি ব্যবহার করতে পারেন। বিকল্প (1) এ থাকাকালীন আপনি testকোনও একক whenট্যাগের বৈশিষ্ট্যে কোনও স্ক্রিপ্টলেট এবং একটি EL প্রকাশ ব্যবহার করতে পারবেন না ।


1
বিকল্প 2 সম্পর্কিত, সংকলক এটি যাচাই করতে পারে না, তবে রানটাইমের সময়ে স্ট্রিংটি এনামে রূপান্তরিত Enum.valueOf(Class<T> enumType, String name)হবে যা ELExceptionএনামের সাথে সেই নামের সাথে কোনও ধ্রুবক না থাকলে একটি ট্রিগার করবে will অভিব্যক্তিটি সর্বদা মিথ্যা হবে না।
পুনরায় বুট করুন

23

সুতরাং আমার সমস্যার পুরোপুরি সমাধানের জন্য আমাকে নিম্নলিখিতগুলি করা দরকার:

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

তারপরে আমি সক্ষম হয়েছি:

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

যা প্রত্যাশা মতো কাজ করেছে।


12
স্ক্রিপ্টলেট ব্যবহার করা খারাপ স্টাইল।
ইউজিন রেটুনস্কি

13

এখানে আরও দুটি সম্ভাবনা রয়েছে:

জেএসপি ইএল 3.0 কনস্ট্যান্টস

আপনি যতক্ষণ না EL এর ন্যূনতম সংস্করণ 3.0 ব্যবহার করছেন ততক্ষণ আপনি নীচের হিসাবে আপনার পৃষ্ঠায় ধ্রুবকগুলি আমদানি করতে পারেন:

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

তবে কিছু আইডিই এখনও এটি বুঝতে পারে না (যেমন ইন্টেলিজ ) তাই রান টাইম অবধি টাইপ বানালে আপনি কোনও সতর্কতা পাবেন না।

এটি সঠিক আইডিই সমর্থন পাওয়ার পরে এটি আমার পছন্দসই পদ্ধতি হবে।

সহায়ক পদ্ধতি

আপনি কেবল আপনার এনামে গেটার যুক্ত করতে পারেন।

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

তারপরে আপনার জেএসপিতে:

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

এটি সমস্ত আইডিইগুলিতে সমর্থিত এবং আপনি যদি এখনও EL 3.0 ব্যবহার করতে না পারেন তবে তাও কাজ করবে। এই মুহুর্তে আমি এটিই করি কারণ এটি সমস্ত যুক্তিগুলিকে আমার এনামে আবৃত করে রাখে।

এছাড়াও ভেরিয়েবলটি এনামের সংরক্ষণের জন্য ভেরিয়েবলের পক্ষে সম্ভব হয় কিনা তা সম্পর্কে সতর্কতা অবলম্বন করুন। আপনার কোডটি যদি গ্যারান্টি দেয় না যে এটি নাল নয়: আপনাকে প্রথমে এটি পরীক্ষা করতে হবে would

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

আমি মনে করি যে এই পদ্ধতিটি আপনি জেএসপিতে মধ্যস্থতাকারী মান নির্ধারণ করেছেন সেখানে তাদের চেয়ে উচ্চতর কারণ আপনাকে প্রতিটি পৃষ্ঠাতে যেখানে এনাম ব্যবহারের প্রয়োজন তা করতে হবে। যাইহোক, এই সমাধানের সাথে আপনার কেবল একবার খালি ঘোষণা করা দরকার।


2
"জেএসপি ইএল 3.0 কনস্ট্যান্টস" অংশটি অবশ্যই গ্রহণযোগ্য উত্তর হতে হবে কারণ অন্তর্নির্মিত কার্যকারিতাটি ব্যবহার করে প্রয়োজনীয় ফলাফল অর্জনের এটি স্ট্যান্ডার্ড উপায়। একপাশে নোটে, ইন্টেলিজ আইডিইএ (কমপক্ষে আলটিমেট সংস্করণ 2017.2.4) এটি বাক্সের বাইরে সমর্থন করে এবং যখন আপনি টাইপ করবেন তখন ${MyEnum.}বিন্দুর পরে ডানদিকে ক্যারেট রাখুন এবং Ctrl+Spaceপরামর্শগুলি দেখানোর জন্য টিপুন available
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());

এটি আমাকে আমার জেএসপি পৃষ্ঠায় নিম্নলিখিতটি ব্যবহার করতে দেয়।

<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()}
  • আমদানিটি শীর্ষে রাখুন , জেএসপি পৃষ্ঠা শিরোনামে
  • আপনি যদি getStatus পদ্ধতিতে কাজ করতে চান তবে # 1 ব্যবহার করুন
  • আপনি যদি এনাম উপাদানটি নিজেই কাজ করতে চান তবে # 2 বা # 3 ব্যবহার করুন
  • আপনি একের পরিবর্তে == ব্যবহার করতে পারেন

-1

আমি সাধারণত jsps / ট্যাগ ফাইলগুলিতে জাভা কোড মিশ্রিত করা খারাপ অভ্যাস বিবেচনা করি। 'এক' ব্যবহার করে কৌশলটি করা উচিত:

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

3
তাহলে এর ==বদলে ব্যবহার করা কি খারাপ অভ্যাস eq? তারা উভয়ই ঠিক একই কাজ করে, তাই "কৌশল" এর কোনও উপায় নেই।
বালুসসি

অবশ্যই, আমি eq বনাম == ব্যবহার সম্পর্কিত কোনও বিবৃতি দিচ্ছিলাম না। এই প্রশ্নের অনেকগুলি উত্তর জাভা কোড জেএসপি বা ট্যাগ ফাইলগুলিতে প্রবেশ করা জড়িত যা কোনও ক্রাচ হতে পারে। আমি জাভা কোডে ব্যবসায়ের লজিক রাখার পক্ষে (যেখানে এটি ইউনিটটি সহজে এবং পুঙ্খানুপুঙ্খভাবে পরীক্ষা করা যেতে পারে) জেএসপিতে প্রদর্শন যুক্তি থেকে পৃথক করে রাখার পক্ষে।
একলাট্যান্ট

7
আমার কাছে আপনার জেএসপিতে ম্যাজিক স্ট্রিং toোকানো সমানভাবে খারাপ অভ্যাস বলে মনে হচ্ছে যা আপনি যখন আপনার এনামগুলিকে রিফেক্টর করতে চান তখন সংকলক দ্বারা এটি পরীক্ষা করা যায় না। দেখে মনে হচ্ছে উভয় পক্ষেই এর কোনও ভাল সমাধান নেই।
লাইল

-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 আপত্তি তৈরি করা হয়। এখন এনামটাইস্ট আপনি সার্লেট বা কন্ট্রোলার ক্লাস সেশন ব্যবহার করে সেশন অবজেক্টে সেট করবেন setसेटএট্রিবিউট ("এনামটেষ্ট", এনামটেষ্ট);

জেএসপি পেজে

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

//TRUE??? THEN PROCESS SOME LOGIC
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.