Pergunta

Eu tenho um Enum chamado Estado definido como tal:

public enum Status { 

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

    private final String val;

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

    public String getStatus() {
        return val;
    }

}

Eu gostaria de acessar o valor de VALID de uma tag JSTL. Especificamente o atributo test da etiqueta <c:when>. Por exemplo.

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

Eu não tenho certeza se isso é possível.

Foi útil?

Solução

Uma comparação simples contra obras de cordas:

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

Outras dicas

Se estiver usando Spring MVC, o Expression Primavera Language (SPEL) pode ser útil:

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

Você tem 3 opções aqui, nenhum dos quais é perfeito:

  1. Você pode usar um scriptlet no atributo test:

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

    Este usa o enum, mas também utiliza um scriptlet, o que não é o "caminho certo" em JSP 2.0. Mas o mais importante, isso não funciona quando você quiser adicionar outra condição para o mesmo when usando ${}. E isso significa todas as variáveis ??que você deseja teste têm de ser declaradas em um scriptlet, ou mantidos em pedido, ou sessão (variável pageContext não está disponível nos arquivos .tag).

  2. Você pode comparar contra string:

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

    Isso parece limpo, mas você está introduzindo uma cadeia que duplica o valor de enumeração e não pode ser validada pelo compilador. Então, se você remover esse valor a partir da enumeração ou renomeá-lo, você não vai ver que esta parte do código não é mais acessível. Você basicamente tem que fazer uma pesquisa / substituir o código de cada vez.

  3. Você pode adicionar cada um dos valores de enumeração que você usa no contexto da página:

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

    e, em seguida, você pode fazer isso:

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

Eu prefiro a última opção (3), embora também utiliza um scriptlet. Isso é porque ele só usa-lo quando você definir o valor. Mais tarde, você pode usá-lo em expressões EL mais complexos, em conjunto com outras condições EL. Enquanto na opção (1) você não pode usar um scriptlet e uma expressão EL no atributo test de uma única tag when.

Assim, para obter o meu problema totalmente resolvido que eu precisava para fazer o seguinte:

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

Então eu era capaz de fazer:

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

que funcionou como esperado.

Aqui estão mais duas possibilidades:

JSP EL 3,0 Constantes

Enquanto você estiver usando pelo menos a versão 3.0 do EL, em seguida, você pode importar constantes em sua página da seguinte forma:

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

No entanto, algumas IDEs não entendem isso ainda (por exemplo IntelliJ ), assim você não terá quaisquer avisos se você cometer um erro de digitação, até a execução.

Este seria o meu método preferido, uma vez que recebe o apoio IDE adequada.

Métodos de Ajuda

Você poderia apenas adicionar getters à sua enumeração.

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

Então em seu JSP:

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

Este é suportado em todas as IDEs e também irá funcionar se você não pode usar EL 3.0 ainda. Isto é o que eu faço no momento, pois ele mantém toda a lógica embrulhado em meu enum.

Também deve ter cuidado se é possível para a variável armazenando o enum para ser nulo. Você precisa verificar para que primeiro se o seu código não garante que não é nulo:

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

Eu acho que este método é superior aos onde você definir um valor intermediário no JSP, porque você tem que fazer isso em cada página onde você precisa usar a enumeração. No entanto, com esta solução só precisa declarar o getter uma vez.

Para este fim eu faço o seguinte:

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

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

É olha feio, mas funciona!

Eu não tenho uma resposta para a questão de Kornel, mas eu tenho uma observação sobre os outros exemplos de scripts. A maior parte da confiança expressão implicitamente na toString(), mas o Enum.valueOf() espera um valor que vem de / corresponde a propriedade Enum.name(). Portanto, deve-se usar por exemplo:.

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

Adicionar um método para o enum como:

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

Por exemplo

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

Em seguida, você pode usar:

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

Ao usar um framework MVC Eu coloquei o seguinte no meu controlador.

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

Isso me permite usar o seguinte no meu JSP página.

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

Ele também pode ser usado em sua comparação

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

O que eu prefiro mais colocando em um literal string.

<%@ 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()}
  • Coloque a importação no top , no cabeçalho da página JSP
  • Se você quiser trabalhar com método getStatus , use # 1
  • Se você quiser trabalhar com o elemento enum em si, use um # 2 ou # 3
  • Você pode usar == em vez de eq

I geralmente consideram má prática de misturar código java em JSPs arquivos / tag. Usando 'eq' deve fazer o truque:

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

Eu fazê-lo desta forma, quando há muitos pontos para usar ...

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

Em Java Class:

    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
}

Então, agora POJO e enum obj é criado. Agora EnumTest você irá definir no objeto de sessão usando na classe servlet ou controlador session.setAttribute ( "enumTest", EnumTest);

Em JSP página

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

//TRUE??? THEN PROCESS SOME LOGIC
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top