在 JSP EL 中连接字符串?

2022-09-03 12:20:45

我有一个豆子列表,每个豆子都有一个属性,它本身就是电子邮件地址列表。

<c:forEach items="${upcomingSchedule}" var="conf">
    <div class='scheduled' title="${conf.subject}" id="scheduled<c:out value="${conf.id}"/>">
    ...
    </div>
</c:forEach>

这将在列表中呈现每个 Bean 一个。<div>

对于子列表,我希望能够做的是连接列表中的每个条目以形成一个字符串,以显示为 属性的一部分。为什么?因为我们使用javascript库(mootools)将其转换为浮动工具提示,而库将其转换为工具提示的文本。<div>title<div>title

因此,如果是“主题”,最终我希望是“主题:blah@blah.com,blah2@blah2.com 等”,包含子列表的所有电子邮件地址。${conf.subject}title<div>

如何使用 JSP EL 执行此操作?我试图远离将脚本块放在jsp文件中。


答案 1

执行此操作的“干净”方法是使用函数。由于 JSTL 函数无法在 上运行,因此您可以毫不费力地编写自己的函数,并在所有位置重用它,而不是剪切和粘贴大量循环代码。joinCollection

您需要函数实现和TLD来让您的Web应用程序知道在哪里可以找到它。把它们放在一个 JAR 中,然后放到你的 WEB-INF/lib 目录中。

以下是概述:

com/x/taglib/core/StringUtil.java

package com.x.taglib.core;

public class StringUtil {

  public static String join(Iterable<?> elements, CharSequence separator) {
    StringBuilder buf = new StringBuilder();
    if (elements != null) {
      if (separator == null)
        separator = " ";
      for (Object o : elements) {
        if (buf.length() > 0)
          buf.append(separator);
        buf.append(o);
      }
    }
    return buf.toString();
  }

}

META-INF/x-c.tld:

<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>
  <short-name>x-c</short-name>
  <uri>http://dev.x.com/taglib/core/1.0</uri>
  <function>
    <description>Join elements of an Iterable into a string.</description>
    <display-name>Join</display-name>
    <name>join</name>
    <function-class>com.x.taglib.core.StringUtil</function-class>
    <function-signature>java.lang.String join(java.lang.Iterable, java.lang.CharSequence)</function-signature>
  </function>
</taglib>

虽然TLD有点冗长,但对于任何使用JSP的开发人员来说,了解自己的方式都是一项很好的技能。而且,由于您已经选择了像JSP这样的标准进行演示,因此您很有可能拥有可以帮助您的工具。

与向基础模型添加更多方法的替代方法相比,此方法具有许多优点。此函数可以编写一次,并在任何项目中重复使用。它适用于闭源第三方库。可以在不同的上下文中支持不同的分隔符,而不会使用每个分隔符的新方法污染模型 API。

最重要的是,它支持视图和模型控制器开发角色的分离。这两个领域的任务通常由不同的人在不同的时间执行。在这些层之间保持松散耦合可以最大限度地降低复杂性和维护成本。即使像在演示文稿中使用不同的分隔符这样的微不足道的更改也需要程序员修改库,那么您就有一个非常昂贵和繁琐的系统。

无论该类是否公开为 EL 函数,该类都是相同的。唯一必要的“额外”是TLD,这是微不足道的;一个工具可以很容易地生成它。StringUtil


答案 2

想出了一个有点肮脏的方法来做到这一点:

<c:forEach items="${upcomingSchedule}" var="conf">
    <c:set var="title" value="${conf.subject}: "/>
    <c:forEach items="${conf.invitees}" var="invitee">
        <c:set var="title" value="${title} ${invitee}, "/>
    </c:forEach>
    <div class='scheduled' title="${title}" id="scheduled<c:out value="${conf.id}"/>">
    ...
    </div>
</c:forEach>

我只是反复使用,引用它自己的值,来附加/连接字符串。<c:set>