list.contains JSTL의 문자열 평가


89

JSP에 특정 값이있는 경우 요소를 숨겨야합니다.

값은 목록에 저장되므로 시도했습니다.

<c:if test="${  mylist.contains( myValue ) }">style='display:none;'</c:if>

그러나 작동하지 않습니다.

목록에 JSTL의 값이 포함되어 있는지, 목록과 값이 문자열인지 어떻게 평가할 수 있습니까?


17
주어진 구문은 EL 2.2 (2009 년 12 월에 출시 된 Servlet 3.0 / JSP 2.2의 일부로 제공됨) 이후 의도 된대로 작동합니다.
BalusC

답변:


70

슬프게도 JSTL은 이것을 알아 내기 위해 모든 요소를 ​​반복하는 것 외에는 아무것도 지원하지 않는다고 생각합니다. 과거에는 핵심 태그 라이브러리에서 forEach 메서드를 사용했습니다.

<c:set var="contains" value="false" />
<c:forEach var="item" items="${myList}">
  <c:if test="${item eq myValue}">
    <c:set var="contains" value="true" />
  </c:if>
</c:forEach>

이 실행 후 myList에 myValue가 포함 된 경우 $ {contains}는 "true"와 같습니다.


10
목록이 작 으면 잘 작동합니다. 이런 식으로 수행하는 데 성능 비용이 있음을 인식하십시오.
Chii

네, 당신이 충분히 높으면있을 것입니다. 나는 그것을 10-20 개의 컬렉션에 사용했으며 성능 문제는 경험하지 않았습니다. 내가 생각하기에 더 나쁜 것은 JSTL의 줄 수입니다. 그래도 자신의 TLD를 설정하지 않는 유일한 방법이라고 생각합니다 (너무 어렵지 않고 그만한 가치가있을 수 있습니다).
Kaleb Brasee

97

이를 확인할 수있는 내장 기능이 없습니다. 목록과 항목을 가져 와서 목록의 contains () 메서드를 호출하는 자체 tld 함수를 작성하면됩니다. 예 :

//in your own WEB-INF/custom-functions.tld file add this
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib
        xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0"
        >
    <tlib-version>1.0</tlib-version>
    <function>
        <name>contains</name>
        <function-class>com.Yourclass</function-class>
        <function-signature>boolean contains(java.util.List,java.lang.Object)
        </function-signature>
    </function>
</taglib>

그런 다음 Yourclass라는 클래스를 만들고 위의 서명을 사용하여 contains라는 정적 메서드를 추가합니다. 나는 그 방법의 구현이 꽤 자명하다고 확신합니다.

package com; // just to illustrate how to represent the package in the tld
public class Yourclass {
   public static boolean contains(List list, Object o) {
      return list.contains(o);
   }
}

그런 다음 jsp에서 사용할 수 있습니다.

<%@ taglib uri="/WEB-INF/custom-functions.tld" prefix="fn" %>
<c:if test="${  fn:contains( mylist, myValue ) }">style='display:none;'</c:if>

태그는 사이트의 모든 JSP에서 사용할 수 있습니다.

편집 : tld 파일에 관한 추가 정보 - 여기에 추가 정보


4
taglib Collection대신 사용 하는 것이 좋습니다 List. 동일하게 작동하지만 Sets 와 같은 더 많은 컬렉션 유형을 지원합니다
Ralph

28

이를 수행하는 또 다른 방법은 Map (HashMap)객체를 나타내는 with Key, Value 쌍을 사용하는 것입니다.

Map<Long, Object> map = new HashMap<Long, Object>();
map.put(new Long(1), "one");
map.put(new Long(2), "two");

JSTL에서

<c:if test="${not empty map[1]}">

쌍이 맵에 있으면 true를 반환해야합니다.


2
이것은 내가 선호하는 방법이며, 뷰에 필요한 모든 것에 대해 뷰 모델에 해시 맵을 설정합니다. EL 구문과 잘 통합되며 검색시 매우 빠릅니다.
Boris B.

한 가지 더, 키가 있지만 값이 null이거나 비어 있으면 false를 반환합니다.
Zai

1
또는지도에 부울이있는 경우 test="${isPresentByValue[myValue]}".
Noumenon 2017

15

fn:contains()또는 fn:containsIgnoreCase()함수 를 사용해야합니다 .

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

...

 <c:if test="${not fn:containsIgnoreCase(mylist, 'apple')}">
        <p>Doesn't contain 'apple'</p>
    </c:if>

또는

<c:if test="${not fn:contains(mylist, 'Apple')}">
            <p>Contains 'Apple'</p>
        </c:if>

참고 : 이 방법은 다음과 같이 작동mylist.toString().contains("apple")하며 이것이 원하는 것이 아닌 경우 다른 방법을 사용하는 것이 좋습니다.


2
이것은 올바른 접근 방식이 아닙니다. 기본적으로 mylist.toString().contains("apple")처음에 예상했던 것과는 전혀 다른 방식으로 작동합니다 .
BalusC

오 .. 그래 이건 내가 기대 하는게 아니야. 어쨌든 나는이 fining으로 내 대답을 업데이트 할 것입니다.
tk_

2

다음은 질문에 대한 답변보다는 해결 방법에 가깝지만 찾고있는 것일 수 있습니다. 목록 대신지도에 값을 넣을 수 있다면 문제가 해결 될 것입니다. 값을 null이 아닌 값에 매핑하고이를 수행 <c:if test="${mymap.myValue ne null}">style='display:none;'</c:if>하거나 매핑 style='display:none;하고 간단히 출력 할 수도 있습니다.${mymap.myValue}


구문은 <c : if test = "$ {mymap [myValue] ne null}"> style = 'display : none;'</ c : if>이어야한다고 생각합니다. 그렇지 않으면 변수 "myValue"가 평가되지 않습니다.
Andreas

2
${fn:contains({1,2,4,8}, 2)}

또는

  <c:if test = "${fn:contains(theString, 'test')}">
     <p>Found test string<p>
  </c:if>

  <c:if test = "${fn:contains(theString, 'TEST')}">
     <p>Found TEST string<p>
  </c:if>

0

EL 3.0+를 사용 하는 경우이 경우 가장 좋은 방법 은 다른 주제에 설명 된 다른 답변같습니다 .

A에 대한 Collection이 쉽게 그냥 사용 Colleciton#contains() EL의 방법을.

<h:panelGroup id="p1" rendered="#{bean.panels.contains('p1')}">...</h:panelGroup>
<h:panelGroup id="p2" rendered="#{bean.panels.contains('p2')}">...</h:panelGroup>
<h:panelGroup id="p3" rendered="#{bean.panels.contains('p3')}">...</h:panelGroup>

를 들어 Object[](배열), 당신은 EL 3.0의 최소 필요하고 새로운 람다 지원을 활용하는 것입니다.

<h:panelGroup id="p1" rendered="#{bean.panels.stream().anyMatch(v -> v == 'p1').get()}">...</h:panelGroup>
<h:panelGroup id="p2" rendered="#{bean.panels.stream().anyMatch(v -> v == 'p2').get()}">...</h:panelGroup>
<h:panelGroup id="p3" rendered="#{bean.panels.stream().anyMatch(v -> v == 'p3').get()}">...</h:panelGroup>

아직 EL 3.0을 사용하고 있지 않다면 사용자 정의 EL 함수를 만들어야합니다. [...]


-1

Spring Framework를 사용하는 경우 Spring TagLib 및 SpEL을 사용할 수 있습니다.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
---
<spring:eval var="containsValue" expression="mylist.contains(myValue)" />
<c:if test="${containsValue}">style='display:none;'</c:if>

-1

이 솔루션이 놀랍다는 것을 알았습니다.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%
   ArrayList list = new ArrayList();
   list.add("one");
   list.add("two");
   list.add("three");
%>
<c:set var="list" value="<%=list%>" />
<html>
<body>
        My list is ${list}<br/>
<c:if test='${fn:contains(list, "two")}'>
        My list contains two <br/>
</c:if>
<c:if test='${fn:contains(list, ",")}'>
        My list contains , 
</c:if>
</body>
</html>

위 코드의 출력은 다음과 같습니다.

내 목록은 [하나, 둘, 셋]

내 목록에는 두 가지가 있습니다.

내 목록에는,

누군가에게 도움이되기를 바랍니다.


-2
<c:if test="${fn:contains(task.subscribers, customer)}">

이것은 나를 위해 잘 작동합니다.


18
이것은 두 요소를 문자열로 변환 한 후 확인하는 것입니다. 목록은 문자열로 변환되며 요소별로 확인되지 않습니다. task.subscribers가 목록 [ "one", "two", "twentyone"]이면 다음과 같습니다. 고객의 경우 true = "one"(두 번 일치) 고객의 경우 false = "three"(일치 없음) 고객의 경우 true = "twenty"(당신이 찾고있는 것이 아님)
Ricardo Marimon 2013

2
rmarimon의 경고를 알고 있으므로이 답변은 정확한 사용 사례와 일치했습니다.
CodeReaper 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.