使用EL和JSTL访问Enum值

时间:2023-01-18 22:15:47

I have an Enum called Status defined as such:

我有一个名为状态定义的Enum:

public enum Status { 

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

    private final String val;

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

    public String getStatus() {
        return val;
    }

}

I would like to access the value of VALID from a JSTL tag. Specifically the test attribute of the <c:when> tag. E.g.

我希望从JSTL标记访问有效值。具体为 标签时的测试属性。如。 当>

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

I'm not sure if this is possible.

我不确定这是否可能。

11 个解决方案

#1


103  

A simple comparison against string works:

一个简单的比较与字符串作品:

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

#2


53  

If using Spring MVC, the Spring Expression Language (SpEL) can be helpful:

如果使用Spring MVC, Spring表达式语言(SpEL)可能会有帮助:

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

#3


36  

You have 3 choices here, none of which is perfect:

你有三个选择,没有一个是完美的:

  1. You can use a scriptlet in the test attribute:

    您可以在test属性中使用scriptlet:

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

    " >

    This uses the enum, but it also uses a scriptlet, which is not the "right way" in JSP 2.0. But most importantly, this doesn't work when you want to add another condition to the same when using ${}. And this means all the variables you want to test have to be declared in a scriptlet, or kept in request, or session (pageContext variable is not available in .tag files).

    这使用了enum,但也使用了scriptlet,这在JSP 2.0中不是“正确的方式”。但最重要的是,当您想在使用${}时将另一个条件添加到相同的条件时,这将不起作用。这意味着您想要测试的所有变量都必须在scriptlet中声明,或者保存在request或session中(.tag文件中不能使用pageContext变量)。

  2. You can compare against string:

    你可以比较字符串:

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

    < c:当测试= " $ { dp。状态= = '有效' } " >

    This looks clean, but you're introducing a string that duplicates the enum value and cannot be validated by the compiler. So if you remove that value from the enum or rename it, you will not see that this part of code is not accessible anymore. You basically have to do a search/replace through the code each time.

    这看起来很干净,但是您引入了一个字符串,它复制了enum值,并且不能被编译器验证。因此,如果您从枚举中删除该值或重命名它,您将不会看到这部分代码已经无法访问。基本上每次都要对代码进行搜索/替换。

  3. You can add each of the enum values you use into the page context:

    您可以将每个枚举值添加到页面上下文中:

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

    < c:设置var = "有效的" value = " < % = Status.VALID % > " / >

    and then you can do this:

    然后你可以这样做:

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

    < c:当测试= " $ { dp。状态= =有效} " >

I prefer the last option (3), even though it also uses a scriptlet. This is because it only uses it when you set the value. Later on you can use it in more complex EL expressions, together with other EL conditions. While in option (1) you cannot use a scriptlet and an EL expression in the test attribute of a single when tag.

我更喜欢最后一个选项(3),尽管它也使用scriptlet。这是因为它只在设置值时使用。稍后,您可以在更复杂的EL表达式中使用它,以及其他EL条件。在选项(1)中,不能在单个when标记的test属性中使用scriptlet和EL表达式。

#4


21  

So to get my problem fully resolved I needed to do the following:

因此,为了彻底解决我的问题,我需要做以下事情:

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

Then I was able to do:

然后我就能做到:

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

which worked as expected.

像预期的那样工作。

#5


9  

For this purposes I do the following:

为此目的,我做以下工作:

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

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

It's looks ugly, but works!

它看起来很丑,但很管用!

#6


6  

Here are two more possibilities:

这里有两种可能性:

JSP EL 3.0 Constants

As long as you are using at least version 3.0 of EL, then you can import constants into your page as follows:

只要您使用至少3.0版本的EL,就可以将常量导入您的页面,如下所示:

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

However, some IDEs don't understand this yet (e.g. IntelliJ) so you won't get any warnings if you make a typo, until runtime.

但是,有些ide还不理解这一点(例如IntelliJ),因此,如果您犯了一个错码,您在运行时之前不会得到任何警告。

This would be my preferred method once it gets proper IDE support.

一旦得到适当的IDE支持,这将是我的首选方法。

Helper Methods

You could just add getters to your enum.

你可以将getter添加到枚举中。

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

Then in your JSP:

然后在JSP:

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

This is supported in all IDEs and will also work if you can't use EL 3.0 yet. This is what I do at the moment because it keeps all the logic wrapped up into my enum.

这在所有ide中都得到了支持,如果您还不能使用EL 3.0,也可以使用它。这就是我现在所做的,因为它把所有的逻辑都集中到我的enum中。

Also be careful if it is possible for the variable storing the enum to be null. You would need to check for that first if your code doesn't guarantee that it is not null:

也要注意,如果可能将枚举存储为空。如果您的代码不保证它不是空的,您需要首先检查它:

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

I think this method is superior to those where you set an intermediary value in the JSP because you have to do that on each page where you need to use the enum. However, with this solution you only need to declare the getter once.

我认为这种方法优于在JSP中设置中间值的方法,因为在需要使用enum的每个页面上都必须这样做。但是,对于这个解决方案,您只需要声明getter一次。

#7


3  

I do not have an answer to the question of Kornel, but I've a remark about the other script examples. Most of the expression trust implicitly on the toString(), but the Enum.valueOf() expects a value that comes from/matches the Enum.name() property. So one should use e.g.:

我没有关于Kornel问题的答案,但是我有一个关于其他脚本示例的评论。toString()上的大多数表达式信任都是隐式的,但是Enum.valueOf()需要来自/匹配Enum.name()属性的值。所以我们应该用例:

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

#8


2  

Add a method to the enum like:

向枚举中添加一个方法,如:

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

For example

例如

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

Then you can use:

然后您可以使用:

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

#9


1  

When using a MVC framework I put the following in my controller.

在使用MVC框架时,我将下面的内容放在控制器中。

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

This allows me to use the following in my JSP Page.

这允许我在JSP页面中使用以下内容。

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

It can also be used in your comparison

它也可以用于你的比较

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

Which I prefer over putting in a string literal.

我更喜欢用字符串文字。

#10


-1  

I generally consider it bad practice to mix java code into jsps/tag files. Using 'eq' should do the trick :

我通常认为将java代码混合到jsp /标记文件中是不好的做法。使用“情商”应该能做到这一点:

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

#11


-2  

In Java Class:

在Java类:

    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
}

So now POJO and enum obj is created. Now EnumTest you will set in session object using in the servlet or controller class session.setAttribute("enumTest", EnumTest );

现在POJO和enum obj已经创建。现在,您将在会话对象中使用servlet或控制器类会话设置EnumTest。setAttribute(“enumTest enumTest);

In JSP Page

在JSP页面

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

//TRUE??? THEN PROCESS SOME LOGIC

#1


103  

A simple comparison against string works:

一个简单的比较与字符串作品:

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

#2


53  

If using Spring MVC, the Spring Expression Language (SpEL) can be helpful:

如果使用Spring MVC, Spring表达式语言(SpEL)可能会有帮助:

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

#3


36  

You have 3 choices here, none of which is perfect:

你有三个选择,没有一个是完美的:

  1. You can use a scriptlet in the test attribute:

    您可以在test属性中使用scriptlet:

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

    " >

    This uses the enum, but it also uses a scriptlet, which is not the "right way" in JSP 2.0. But most importantly, this doesn't work when you want to add another condition to the same when using ${}. And this means all the variables you want to test have to be declared in a scriptlet, or kept in request, or session (pageContext variable is not available in .tag files).

    这使用了enum,但也使用了scriptlet,这在JSP 2.0中不是“正确的方式”。但最重要的是,当您想在使用${}时将另一个条件添加到相同的条件时,这将不起作用。这意味着您想要测试的所有变量都必须在scriptlet中声明,或者保存在request或session中(.tag文件中不能使用pageContext变量)。

  2. You can compare against string:

    你可以比较字符串:

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

    < c:当测试= " $ { dp。状态= = '有效' } " >

    This looks clean, but you're introducing a string that duplicates the enum value and cannot be validated by the compiler. So if you remove that value from the enum or rename it, you will not see that this part of code is not accessible anymore. You basically have to do a search/replace through the code each time.

    这看起来很干净,但是您引入了一个字符串,它复制了enum值,并且不能被编译器验证。因此,如果您从枚举中删除该值或重命名它,您将不会看到这部分代码已经无法访问。基本上每次都要对代码进行搜索/替换。

  3. You can add each of the enum values you use into the page context:

    您可以将每个枚举值添加到页面上下文中:

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

    < c:设置var = "有效的" value = " < % = Status.VALID % > " / >

    and then you can do this:

    然后你可以这样做:

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

    < c:当测试= " $ { dp。状态= =有效} " >

I prefer the last option (3), even though it also uses a scriptlet. This is because it only uses it when you set the value. Later on you can use it in more complex EL expressions, together with other EL conditions. While in option (1) you cannot use a scriptlet and an EL expression in the test attribute of a single when tag.

我更喜欢最后一个选项(3),尽管它也使用scriptlet。这是因为它只在设置值时使用。稍后,您可以在更复杂的EL表达式中使用它,以及其他EL条件。在选项(1)中,不能在单个when标记的test属性中使用scriptlet和EL表达式。

#4


21  

So to get my problem fully resolved I needed to do the following:

因此,为了彻底解决我的问题,我需要做以下事情:

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

Then I was able to do:

然后我就能做到:

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

which worked as expected.

像预期的那样工作。

#5


9  

For this purposes I do the following:

为此目的,我做以下工作:

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

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

It's looks ugly, but works!

它看起来很丑,但很管用!

#6


6  

Here are two more possibilities:

这里有两种可能性:

JSP EL 3.0 Constants

As long as you are using at least version 3.0 of EL, then you can import constants into your page as follows:

只要您使用至少3.0版本的EL,就可以将常量导入您的页面,如下所示:

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

However, some IDEs don't understand this yet (e.g. IntelliJ) so you won't get any warnings if you make a typo, until runtime.

但是,有些ide还不理解这一点(例如IntelliJ),因此,如果您犯了一个错码,您在运行时之前不会得到任何警告。

This would be my preferred method once it gets proper IDE support.

一旦得到适当的IDE支持,这将是我的首选方法。

Helper Methods

You could just add getters to your enum.

你可以将getter添加到枚举中。

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

Then in your JSP:

然后在JSP:

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

This is supported in all IDEs and will also work if you can't use EL 3.0 yet. This is what I do at the moment because it keeps all the logic wrapped up into my enum.

这在所有ide中都得到了支持,如果您还不能使用EL 3.0,也可以使用它。这就是我现在所做的,因为它把所有的逻辑都集中到我的enum中。

Also be careful if it is possible for the variable storing the enum to be null. You would need to check for that first if your code doesn't guarantee that it is not null:

也要注意,如果可能将枚举存储为空。如果您的代码不保证它不是空的,您需要首先检查它:

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

I think this method is superior to those where you set an intermediary value in the JSP because you have to do that on each page where you need to use the enum. However, with this solution you only need to declare the getter once.

我认为这种方法优于在JSP中设置中间值的方法,因为在需要使用enum的每个页面上都必须这样做。但是,对于这个解决方案,您只需要声明getter一次。

#7


3  

I do not have an answer to the question of Kornel, but I've a remark about the other script examples. Most of the expression trust implicitly on the toString(), but the Enum.valueOf() expects a value that comes from/matches the Enum.name() property. So one should use e.g.:

我没有关于Kornel问题的答案,但是我有一个关于其他脚本示例的评论。toString()上的大多数表达式信任都是隐式的,但是Enum.valueOf()需要来自/匹配Enum.name()属性的值。所以我们应该用例:

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

#8


2  

Add a method to the enum like:

向枚举中添加一个方法,如:

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

For example

例如

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

Then you can use:

然后您可以使用:

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

#9


1  

When using a MVC framework I put the following in my controller.

在使用MVC框架时,我将下面的内容放在控制器中。

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

This allows me to use the following in my JSP Page.

这允许我在JSP页面中使用以下内容。

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

It can also be used in your comparison

它也可以用于你的比较

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

Which I prefer over putting in a string literal.

我更喜欢用字符串文字。

#10


-1  

I generally consider it bad practice to mix java code into jsps/tag files. Using 'eq' should do the trick :

我通常认为将java代码混合到jsp /标记文件中是不好的做法。使用“情商”应该能做到这一点:

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

#11


-2  

In Java Class:

在Java类:

    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
}

So now POJO and enum obj is created. Now EnumTest you will set in session object using in the servlet or controller class session.setAttribute("enumTest", EnumTest );

现在POJO和enum obj已经创建。现在,您将在会话对象中使用servlet或控制器类会话设置EnumTest。setAttribute(“enumTest enumTest);

In JSP Page

在JSP页面

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

//TRUE??? THEN PROCESS SOME LOGIC