문제

나는 콩 목록이 있으며, 각각은 이메일 주소 목록 인 속성이 있습니다.

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

이것은 하나를 만듭니다 <div> 목록에 콩 당.

Subrist의 경우, 내가 할 수있는 것은 목록의 각 항목을 단일 문자열을 형성하여 <div>'에스 title 기인하다. 왜요? 우리는 JavaScript 라이브러리 (mootools)를 사용하여 이것을 돌리기 때문에 <div> 플로팅 도구 팁으로, 라이브러리가 title 툴팁의 텍스트로.

그래서 만약 ${conf.subject} "주제"였고 궁극적으로 나는 원한다 title<div> "제목 : blah@blah.com, blah2@blah2.com 등", 하위 목록의 모든 이메일 주소가 포함되어 있습니다.

JSP EL을 사용하여 어떻게해야합니까? JSP 파일에 스크립트 클록을 넣지 않으려 고합니다.

도움이 되었습니까?

해결책 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> 반복적으로, 그 자체의 가치를 참조하여 문자열을 추가/연결합니다.

다른 팁

이를 수행하는 "깨끗한"방법은 함수를 사용하는 것입니다. JSTL로 join 기능은 작동하지 않습니다 Collection, 당신은 너무 많은 문제없이 자신의 글을 쓰고, 큰 루프 코드를 잘라내 지 않고 장소 전체에서 재사용 할 수 있습니다.

웹 애플리케이션에서 찾을 위치를 알리려면 기능 구현과 TLD가 필요합니다. 이것들을 병에 넣고 웹 -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/xc.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를 오염시키지 않으면 서 서로 다른 구분자를 다른 컨텍스트에서 지원할 수 있습니다.

가장 중요한 것은, 시야 및 모델 제어기 개발 역할을 지원합니다. 이 두 영역의 작업은 종종 다른 사람들이 다른 시간에 수행됩니다. 이 계층 간의 느슨한 커플 링을 유지하면 복잡성과 유지 보수 비용이 최소화됩니다. 프레젠테이션에서 다른 구분표를 사용하는 것과 같은 사소한 변화조차도 프로그래머가 라이브러리를 수정 해야하는 경우 매우 비싸고 번거로운 시스템이 있습니다.

그만큼 StringUtil 클래스는 EL 기능으로 노출 되든 동일합니다. 필요한 유일한 "추가"는 TLD이며, 이는 사소한 것입니다. 도구가 쉽게 생성 할 수 있습니다.

이것을 사용할 수 있습니까? 목록 대신 배열을 원하는 것 같습니다 ..

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

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

Subrist가 Arraylist이고 다음을 수행하는 경우 :

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

당신은 당신이 필요한 것을 거의 얻습니다.

유일한 차이점은 제목이 "제목 : [blah@blah.com, blah2@blah2.com 등]입니다.

아마도 당신에게 충분할 수 있습니다.

나는 이것이 당신이 원하는 것이라고 생각합니다.

<c:forEach var="tab" items="${tabs}">
 <c:set var="tabAttrs" value='${tabAttrs} ${tab.key}="${tab.value}"'/>
</c:forEach>

이 경우 탭 ID (키) 및 URL (값)이있는 해시 맵이있었습니다. Tabattrs 변수는 이전에 설정되지 않았습니다. 따라서 값을 Tabattrs ( ''시작)의 현재 값과 키/값 표현식으로 설정합니다.

문자열을 다음과 같이 서버에서 바이 사이드 바이 사이드를 넣으십시오.

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

         id="scheduled${conf.id}">

    ...
    </div>
</c:forEach>

너무 늦었다 !!!

TAG 라이브러리가 구현되는 방식은 원래 게시 된 이후로 상당히 움직 인 것으로 보입니다. 그래서 나는 일을 작동시키기 위해 약간의 변화를 일으켰습니다. 나의 최종 결과는 다음과 같습니다.

태그 라이브러리 파일 :

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
  <tlib-version>1.0</tlib-version>
  <short-name>string_util</short-name>
  <uri>/WEB-INF/tlds/string_util</uri>
  <info>String Utilities</info>
  <tag>
    <name>join</name>
    <info>Join the contents of any iterable using a separator</info>
    <tag-class>XXX.taglib.JoinObjects</tag-class>
    <body-content>tagdependent</body-content>
    <attribute>
      <name>iterable</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.Iterable</type>
    </attribute>
    <attribute>
      <name>separator</name>
      <required>false</required>
      <rtexprvalue>false</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
  </tag>

  <tag>
    <name>joinints</name>
    <info>Join the contents of an integer array using a separator</info>
    <tag-class>XXX.taglib.JoinInts</tag-class>
    <body-content>tagdependent</body-content>
    <attribute>
      <name>integers</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.Integer[]</type>
    </attribute>
    <attribute>
      <name>separator</name>
      <required>false</required>
      <rtexprvalue>false</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
  </tag>
</taglib>

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}), <su:joinints integers="${row.value}" separator="," />],

EL 3.0 스트림 API를 사용할 수 있습니다. 예를 들어 문자열 목록이있는 경우

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

Ex에 대한 개체 목록이있는 경우. Person (FirstName, LastName) 및 귀하는 그 자산의 한 속성 만 동의하고 싶습니다 (Ex FirstName) Map을 사용할 수 있습니다.

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

귀하의 경우에는 그런 것을 사용할 수 있습니다 (마지막 ','또한 제거),

<c:forEach items="${upcomingSchedule}" var="conf">
    <c:set var="separator" value=","/>
    <c:set var="titleFront" value="${conf.subject}: "/>
    <c:set var="titleEnd" value="${conf.invitees.stream().reduce(separator, (n,p)->p.concat(n))}"/>
    <div class='scheduled' title="${titleFront} ${titleEnd.isEmpty() ? "" : titleEnd.substring(0, titleEnd.length()-1)}" id="scheduled<c:out value="${conf.id}"/>">
    ...
    </div>
</c:forEach>

조심하세요! 그만큼 EL 3.0 스트림 API 전에 마무리되었습니다 Java 8 스트림 API와 그것과 다릅니다. 그들은 뒤로 호환성을 깨뜨리기 때문에 두 가지 모두를 햇볕에 쬐 수 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top