在JSP EL中连接字符串?

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

 <div class='scheduled' title="${conf.subject}" id="scheduled"> ... 

这会在List中为每个bean呈现一个

对于子列表,我希望能够做的是连接列表中的每个条目以形成单个String,以显示为

title属性的一部分。 为什么? 因为我们使用javascript库(mootools)将此

转换为浮动工具提示,并且库将title转换为工具提示的文本。

所以,如果${conf.subject}是“主题”,最终我希望

title是“主题:blah @ blah.com,blah2 @ blah2.com等”,包含所有子列表的电子邮件地址。

我怎么能用JSP EL做到这一点? 我试图远离jsp文件中的scriptlet块。

“干净”的方法是使用一个函数。 由于JSTL join函数不适用于Collection ,因此您可以编写自己的函数而不会遇到太多麻烦,并且可以在整个地方重复使用它,而不是剪切和粘贴大量的循环代码。

您需要function实现和TLD,以便让您的Web应用程序知道在哪里找到它。 将它们放在JAR中并将其放入WEB-INF / lib目录中。

这是一个大纲:

COM / X /标签库/核心/ 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 / xc.tld:

  1.0 xc http://dev.x.com/taglib/core/1.0  Join elements of an Iterable into a string. Join join com.x.taglib.core.StringUtil java.lang.String join(java.lang.Iterable, java.lang.CharSequence)   

虽然顶级域名(TLD)有点冗长,但对于使用JSP的任何开发人员来说,了解自己的方法是一项很好的技能。 而且,既然您已经选择了像JSP这样的标准进行演示,那么您很有可能拥有可以帮助您的工具。

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

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

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

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

      
"> ...

我只是重复使用 ,引用它自己的值,来追加/连接字符串。

你能用这个吗? 好像它想要一个数组而不是一个列表..

 ${fn:join(array, ";")} 

http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/fn/join.fn.html

如果您的子列表是ArrayList,则执行此操作:

 

你几乎得到了你所需要的东西。

唯一的区别是标题是:“主题:[blah@blah.com,blah2@blah2.com等]”。

也许对你来说足够好。

我想这就是你想要的:

    

在这种情况下,我有一个带有选项卡ID(键)和URL(值)的哈希映射。 之前未设置tabAttrs变量。 所以它只是将值设置为tabAttrs的当前值(”开始)加上键/值表达式。

只需将字符串放在服务器的var旁边,如下所示:

  
...

太晚了!!!

标签库的实现方式似乎已经发生了很大的变化,因为这个答案最初发布了,所以我最终做了一些重大改变以使工作正常。 我的最终结果是:

标签库文件:

   1.0 string_util /WEB-INF/tlds/string_util String Utilities  join Join the contents of any iterable using a separator XXX.taglib.JoinObjects tagdependent  iterable true true java.lang.Iterable   separator false false java.lang.String    joinints Join the contents of an integer array using a separator XXX.taglib.JoinInts tagdependent  integers true true java.lang.Integer[]   separator false false java.lang.String    

JoinInts.java

 public class JoinInts extends TagSupport { int[] integers; String separator = ","; @Override public int doStartTag() throws JspException { if (integers != null) { StringBuilder buf = new StringBuilder(); if (separator == null) { separator = " "; } for (int i: integers) { if (buf.length() > 0) { buf.append(separator); } buf.append(i); } try { pageContext.getOut().print(buf); } catch (IOException ex) { Logger.getLogger(JoinInts.class.getName()).log(Level.SEVERE, null, ex); } } return SKIP_BODY; } @Override public int doEndTag() throws JspException { return EVAL_PAGE; } public int[] getIntegers() { return integers; } public void setIntegers(int[] integers) { this.integers = integers; } public String getSeparator() { return separator; } public void setSeparator(String separator) { this.separator = separator; } } 

要使用它:

 <%@ taglib prefix="su" uri="/WEB-INF/tlds/string_util.tld" %> [new Date(${row.key}), ], 

您可以使用EL 3.0 Stream API。 例如,如果您有一个字符串列表,

 
${stringList.stream().reduce(",", (n,p)->p.concat(n))}

如果你有一个ex的对象列表。 Person(firstName,lastName)并且你只想连接它们的一个属性(ex firstName)你可以使用map,

 
${personList.stream().map(p->p.getFirstName()).reduce(",", (n,p)->p.concat(n))}

在你的情况下你可以使用类似的东西(删除最后一个’,’也),

     
"> ...

小心! EL 3.0 Stream API在Java 8 Stream API之前完成,它与此不同。 他们不能同时使用api,因为它会破坏向后兼容性。