قم بالوصول إلى قيمة التعداد باستخدام EL مع JSTL

StackOverflow https://stackoverflow.com/questions/123598

  •  02-07-2019
  •  | 
  •  

سؤال

لدي تعداد يسمى الحالة محددًا على هذا النحو:

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

لست متأكدا إذا كان هذا ممكنا.

هل كانت مفيدة؟

المحلول

مقارنة بسيطة مع أعمال السلسلة:

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

نصائح أخرى

إذا كنت تستخدم Spring MVC، فيمكن أن تكون لغة Spring Expression Language (SpEL) مفيدة:

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

لديك 3 خيارات هنا، لا شيء منها مثالي:

  1. يمكنك استخدام البرنامج النصي في test يصف:

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

    يستخدم هذا التعداد، ولكنه يستخدم أيضًا برنامجًا نصيًا، وهو ليس "الطريقة الصحيحة" في JSP 2.0.ولكن الأهم من ذلك، أن هذا لا يعمل عندما تريد إضافة شرط آخر لنفسه 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)، لا يمكنك استخدام برنامج نصي وتعبير EL في test صفة واحدة when بطاقة شعار.

لذا لحل مشكلتي بالكامل، كان علي القيام بما يلي:

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

ثم تمكنت من القيام بما يلي:

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

والتي عملت كما هو متوقع.

وهنا احتمالان آخران:

ثوابت JSP EL 3.0

طالما أنك تستخدم الإصدار 3.0 على الأقل من EL، فيمكنك استيراد الثوابت إلى صفحتك كما يلي:

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

ومع ذلك، فإن بعض بيئات التطوير المتكاملة لا تفهم هذا بعد (على سبيل المثال. IntelliJ) لذلك لن تحصل على أي تحذيرات إذا قمت بخطأ مطبعي، حتى وقت التشغيل.

ستكون هذه هي الطريقة المفضلة لدي بمجرد حصولها على دعم IDE المناسب.

الأساليب المساعدة

يمكنك فقط إضافة الحروف إلى التعداد الخاص بك.

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

هذا مدعوم في جميع بيئات التطوير المتكاملة وسيعمل أيضًا إذا لم تتمكن من استخدام EL 3.0 حتى الآن.هذا ما أفعله في الوقت الحالي لأنه يبقي كل المنطق متضمنًا في التعداد الخاص بي.

كن حذرًا أيضًا إذا كان من الممكن أن يكون المتغير الذي يخزن التعداد فارغًا.ستحتاج إلى التحقق من ذلك أولاً إذا كان الكود الخاص بك لا يضمن أنه ليس فارغًا:

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

أعتقد أن هذه الطريقة أفضل من تلك التي تقوم فيها بتعيين قيمة وسيطة في JSP لأنه يتعين عليك القيام بذلك في كل صفحة تحتاج فيها إلى استخدام التعداد.ومع ذلك، مع هذا الحل، ما عليك سوى الإعلان عن المُحصل مرة واحدة.

ولهذا الغرض أقوم بما يلي:

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

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

يبدو الأمر قبيحًا، لكنه يعمل!

ليس لدي إجابة على سؤال Kornel، لكن لدي ملاحظة حول أمثلة النصوص الأخرى.معظم التعبير يثق ضمنيًا في toString(), ، لكن ال Enum.valueOf() تتوقع قيمة تأتي من/تطابق Enum.name() ملكية.لذلك يجب على المرء أن يستخدم على سبيل المثال:

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

أضف طريقة إلى التعداد مثل:

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>

عند استخدام إطار عمل MVC أضع ما يلي في وحدة التحكم الخاصة بي.

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

الذي أفضله على وضع سلسلة حرفية.

<%@ 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
  • يمكنك استخدام == بدلاً من مكافئ

أعتبر بشكل عام أنه من الممارسات السيئة خلط تعليمات Java البرمجية في ملفات jsps/tag.يجب أن يؤدي استخدام "eq" إلى القيام بالخدعة:

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

أفعل ذلك بهذه الطريقة عندما يكون هناك العديد من النقاط التي يمكن استخدامها ...

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

في فئة جافا:

    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 ستقوم بتعيين كائن جلسة باستخدام SERVELT أو CONTROLRER CLASS SETATION.SetAttribute ("EnumTest" ، enumtest) ؛

في صفحة جي إس بي

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

//TRUE??? THEN PROCESS SOME LOGIC
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top