[java] JSTL과 함께 EL을 사용하여 Enum 값에 액세스

다음과 같이 정의 된 Status라는 Enum이 있습니다.

public enum Status { 

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

    private final String val;

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

    public String getStatus() {
        return val;
    }

}

VALIDJSTL 태그 의 값에 액세스하고 싶습니다 . 특히 태그 의 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) test에서는 단일 when태그 의 속성에 스크립틀릿과 EL 표현식을 사용할 수 없습니다 .


답변

따라서 내 문제를 완전히 해결하려면 다음을 수행해야했습니다.

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

그러나 일부 IDE는 아직이를 이해하지 못 하므로 (예 : 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}">

이것은 모든 IDE에서 지원되며 아직 EL 3.0을 사용할 수없는 경우에도 작동합니다. 이것은 모든 논리를 내 열거 형으로 묶어두기 때문에 지금 내가하는 일입니다.

또한 열거 형을 저장하는 변수가 null이 될 수있는 경우에도주의하십시오. 코드가 null이 아님을 보장하지 않는 경우 먼저 확인해야합니다.

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

이 방법은 열거 형을 사용해야하는 각 페이지에서 설정해야하기 때문에 JSP에서 중간 값을 설정하는 방법보다 우수하다고 생각합니다. 그러나이 솔루션에서는 getter를 한 번만 선언하면됩니다.


답변

이를 위해 다음을 수행합니다.

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