JSTLでlist.contains文字列を評価する


88

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、2012年

回答:


69

残念ながら、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)、オブジェクトを表すキーと値のペアを使用することです。

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.

もう1つ、キーは存在するが値がnullまたは空の場合、falseを返します。
ザイ

1
またはMAPは、ブール値を保持している場合test="${isPresentByValue[myValue]}"
Noumenon 2017

14

fn:contains()or 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

ああ..そう、これは私が期待するものではありません。とにかく、私はこの微調整で私の答えを更新します。
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+を使用している場合、この場合の最良のアプローチは、この別の回答が別のトピックで説明されているとおりです。

それは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>

上記のコードの出力は

私のリストは[1、2、3]です

私のリストには2つが含まれています

私のリストには、

誰かのお役に立てば幸いです。


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

これでうまくいきます。


18
これは、両方の要素を文字列に変換した後にチェックを行います。リストは文字列に変換され、要素ごとにチェックされません。task.subscribersがリスト["one"、 "two"、 "twentyone"]の場合、次のようになります。顧客の場合はtrue =「1」(2回一致する)顧客の場合はfalse =「3」(一致しない)顧客の場合はtrue = "twenty"(これはあなたが見ているものではありません)
Ricardo Marimon

2
rmarimonの警告に気づいて、この答えは私の正確な使用例と一致しました。
CodeReaper 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.