List.contains dizeyi JSTL'de değerlendirin


89

JSP'de belirli değerler varsa bir öğeyi gizlemem gerekiyor

Değerler bir Listede saklanıyor, ben de denedim:

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

Ama işe yaramıyor.

Bir listenin JSTL'de bir değer içermesi, liste ve değerlerin dizeler olup olmadığını nasıl değerlendirebilirim?


17
Verilen sözdiziminin EL 2.2'den beri amaçlandığı gibi çalıştığına dikkat edin (Aralık 2009'da yayınlanan Servlet 3.0 / JSP 2.2'nin bir parçası olarak getirilmiştir).
BalusC

Yanıtlar:


70

Ne yazık ki, JSTL'nin bunu anlamak için tüm unsurları kapsayan bir yinelemeden başka hiçbir şeyi desteklemediğini düşünüyorum. Geçmişte, çekirdek etiket kitaplığında forEach yöntemini kullandım:

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

Bu çalıştırmalardan sonra, myList değeri myValue içeriyorsa, $ {içerir} "true" değerine eşit olacaktır.


10
liste küçükse güzel çalışır. Bu şekilde yapmanın bir performans maliyeti olduğunun farkına varın.
Chii

Evet, yeterince yükseğe çıkarsan olur. 10-20 şeyden oluşan koleksiyonlar için kullandım ve herhangi bir performans sorunu yaşamadım. Daha kötü olduğunu düşündüğüm şey, JSTL'nin satır sayısı. Yine de, kendi TLD'nizi kurmadan tek yolun bu olduğunu düşünüyorum (ki bu çok zor değil ve buna değer olabilir).
Kaleb Brasee

98

bunu kontrol etmek için yerleşik bir özellik yoktur - yapacağınız şey, bir liste ve bir öğe alan ve listenin contains () yöntemini çağıran kendi tld işlevinizi yazmaktır. Örneğin

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

Ardından, Sınıfınız adında bir sınıf oluşturun ve yukarıdaki imzayla içerir adlı statik bir yöntem ekleyin. Eminim bu yöntemin uygulanması oldukça açıklayıcıdır:

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

O zaman jsp'nizde kullanabilirsiniz:

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

Etiket, sitedeki herhangi bir JSP'den kullanılabilir.

düzenleme: tld dosyasıyla ilgili daha fazla bilgi - daha fazla bilgi burada


4
Taglib Collectionyerine kullanmanızı tavsiye ederim List- aynı şekilde çalışır ancak Sets gibi daha fazla koleksiyon türünü destekler
Ralph

28

Bunu yapmanın başka bir yolu, Map (HashMap)nesnenizi temsil eden Anahtar, Değer çiftleri kullanmaktır.

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

JSTL'de

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

Çift haritada mevcutsa bu doğru döndürmelidir


2
Bu benim de tercih ettiğim yoldur, bir görünümde ihtiyaç duyacağım her şey için görünüm modelinde hashmap'ler ayarlayın. EL sözdizimi ile güzel bir şekilde bütünleşirler ve arama sırasında yıldırım hızındadırlar.
Boris B.

Sadece bir şey daha var, eğer anahtar varsa, ancak değer null veya boşsa, o zaman yanlış döndürür.
Zai

1
Veya Harita boolean içeriyorsa test="${isPresentByValue[myValue]}",.
Noumenon

15

fn:contains()Veya fn:containsIgnoreCase()işlevini kullanmanız gerekir .

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

veya

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

Not: Bu şekilde çalışacaktırmylist.toString().contains("apple")ve aradığınız bu değilse başka bir yaklaşım daha iyi kullanın.


2
Bu doğru yaklaşım değil. Temelde mylist.toString().contains("apple"), başlangıçta kesinlikle beklediğiniz gibi davranmayacaktır .
BalusC

ohh .. evet, beklediğim bu değil. Neyse, cevabımı bu cezayla güncelleyeceğim.
tk_

2

Aşağıdakiler, sorunuzun cevabından çok geçici bir çözümdür, ancak aradığınız şey olabilir. Değerlerinizi liste yerine bir haritaya koyabilirseniz, bu sorununuzu çözecektir. Değerlerinizi boş olmayan bir değerle eşleştirin ve bunu yapın <c:if test="${mymap.myValue ne null}">style='display:none;'</c:if>veya hatta eşleyebilir style='display:none;ve basitçe çıktı alabilirsiniz${mymap.myValue}


Sözdiziminin <c: if test = "$ {mymap [myValue] ne null}"> style = 'display: none;' </ c: if> olması gerektiğini tahmin ediyorum. Aksi takdirde "myValue" değişkeni değerlendirilmez.
Andreas

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

VEYA

  <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+ kullanıyorsanız , bu durumda en iyi yaklaşım, bu diğer cevabın başka bir konuda açıklanan şeklidir:

Bir İçin Collectionbu kolay, sadece kullanmak Colleciton#contains() EL yöntemi.

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

Bir Object[](dizi) için minimum EL 3.0'a ihtiyacınız olacak ve yeni Lambda desteğinden yararlanacaksınız.

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

Henüz EL 3.0'da değilseniz, özel bir EL işlevi oluşturmanız gerekir. [...]


-1

Spring Framework kullanıyorsanız, Spring TagLib ve SpEL'i kullanabilirsiniz:

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

Bu çözümü harika buldum.

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

Yukarıdaki kodun çıktısı

Listem [bir, iki, üç]

Listem iki tane içeriyor

Listem şunları içerir:

Umarım birine yardımcı olur.


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

Bu benim için iyi çalışıyor.


18
Bu, her iki öğeyi dizeye dönüştürdükten sonra kontrolü yapmaktır. Liste bir dizeye dönüştürülür ve her öğe için kontrol edilmez. Task.subscribers bir liste ise ["bir", "iki", "yirmi kişi"] ise: müşteri için doğru = "bir" (iki kez eşleştirme) müşteri için yanlış = "üç" (eşleşme yok) müşteri için true = "yirmi" (aradığınız şey değil)
Ricardo Marimon

2
Rmarimon uyarısının farkında olarak, bu cevap benim tam kullanım durumumla eşleşti.
CodeReaper
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.