문제

다음과 같은 Java Bean이 있습니다.

class Person {
  int age;
  String name;
}

JSP에서 이러한 빈 컬렉션을 반복하여 각 사람을 HTML 테이블 행에 표시하고 테이블의 마지막 행에 모든 연령의 합계를 표시하고 싶습니다.

테이블 행을 생성하는 코드는 다음과 같습니다.

<c:forEach var="person" items="${personList}">
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>

하지만 마지막 행에 표시될 연령 합계를 계산하는 방법을 찾는 데 어려움을 겪고 있습니다. 스크립틀릿 코드를 사용하지 않고, 어떤 제안이 있나요?

도움이 되었습니까?

해결책

메모: 포괄적인 목록을 만들기 위해 답변을 결합해 보았습니다.나는 그것이 필요한 곳에 신용을 부여하기 위해 적절한 곳에 이름을 언급했습니다.

이 문제를 해결하는 방법에는 여러 가지가 있으며 각각의 장단점이 있습니다.

순수 JSP 솔루션

위에서 언급한 ScArcher2처럼 문제에 대한 매우 쉽고 간단한 해결책은 다음과 같이 JSP에서 직접 구현하는 것입니다.

<c:set var="ageTotal" value="${0}" />
<c:forEach var="person" items="${personList}">
  <c:set var="ageTotal" value="${ageTotal + person.age}" />
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${ageTotal}

이 솔루션의 문제점은 JSP가 스크립트를 도입했을 정도로 혼란스러워진다는 것입니다.페이지를 보는 모든 사람이 현재의 기본적인 논리를 따를 수 있을 것으로 예상한다면 이는 좋은 선택입니다.

순수 EL 솔루션

이미 EL 3.0(Java EE 7/Servlet 3.1)을 사용하고 있다면 다음에 대한 새로운 지원을 사용하세요. 스트림과 람다:

<c:forEach var="person" items="${personList}">
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${personList.stream().map(person -> person.age).sum()}

JSP EL 함수

JSP에 스크립트 코드를 도입하지 않고 합계를 출력하는 또 다른 방법은 EL 함수를 사용하는 것입니다.EL 함수를 사용하면 공용 클래스에서 공용 정적 메서드를 호출할 수 있습니다.예를 들어 컬렉션을 반복하고 값의 합을 계산하려는 경우 공개 클래스(PersonUtils라고 함)에서 sum(List people)이라는 공개 정적 메서드를 정의할 수 있습니다.Tld 파일에 다음 선언을 배치합니다.

<function>
  <name>sum</name>
  <function-class>com.example.PersonUtils</function-class>
  <function-signature>int sum(java.util.List people)</function-signature>
</function> 

JSP 내에서 다음과 같이 작성합니다.

<%@ taglib prefix="f" uri="/your-tld-uri"%>
...
<c:out value="${f:sum(personList)}"/>

JSP EL 함수에는 몇 가지 이점이 있습니다.이를 통해 특정 UI(사용자 정의 태그 라이브러리)에 코딩할 필요 없이 기존 Java 메소드를 사용할 수 있습니다.또한 컴팩트하며 프로그래밍에 관심이 없는 사람도 혼동하지 않을 것입니다.

맞춤 태그

또 다른 옵션은 자신만의 맞춤 태그를 굴리는 것입니다.이 옵션에는 대부분의 설정이 필요하지만 기본적으로 찾고 있는 것을 제공하며 스크립틀릿은 전혀 제공하지 않습니다.간단한 사용자 정의 태그 사용에 대한 훌륭한 튜토리얼은 다음에서 찾을 수 있습니다. http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags5.html#74701

관련된 단계에는 TagSupport의 서브클래싱이 포함됩니다.

public PersonSumTag extends TagSupport {

   private List personList;

   public List getPersonList(){
      return personList;
   }

   public void setPersonList(List personList){
      this.personList = personList;
   }

   public int doStartTag() throws JspException {
      try {
        int sum = 0;
        for(Iterator it = personList.iterator(); it.hasNext()){
          Person p = (Person)it.next();
          sum+=p.getAge();
        } 
        pageContext.getOut().print(""+sum);
      } catch (Exception ex) {
         throw new JspTagException("SimpleTag: " + 
            ex.getMessage());
      }
      return SKIP_BODY;
   }
   public int doEndTag() {
      return EVAL_PAGE;
   }
}

tld 파일에 태그를 정의합니다.

<tag>
   <name>personSum</name>
   <tag-class>example.PersonSumTag</tag-class>
   <body-content>empty</body-content>
   ...
   <attribute>
      <name>personList</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.util.List</type>
   </attribute>
   ...
</tag>

JSP 상단에 taglib를 선언합니다.

<%@ taglib uri="/you-taglib-uri" prefix="p" %>

태그를 사용하세요.

<c:forEach var="person" items="${personList}">
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
<p:personSum personList="${personList}"/>

디스플레이 태그

앞서 언급한 zmf처럼 적절한 라이브러리를 포함해야 하지만 표시 태그를 사용할 수도 있습니다.

http://displaytag.sourceforge.net/11/tut_basic.html

다른 팁

모든 연령을 합산하려고 하시나요?

컨트롤러에서 이를 계산하고 jsp에만 결과를 표시할 수 있습니다.

계산을 수행하기 위해 사용자 정의 태그를 작성할 수 있습니다.

이와 같이 jstl을 사용하여 jsp에서 계산할 수 있습니다.

<c:set var="ageTotal" value="${0}" />
<c:forEach var="person" items="${personList}">
  <c:set var="ageTotal" value="${ageTotal + person.age}" />
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${ageTotal}

디스플레이 태그를 확인하세요. http://displaytag.sourceforge.net/11/tut_basic.html

ScArcher2는 가장 간단합니다. 해결책.가능한 한 컴팩트한 것을 원한다면 "sum" 함수가 포함된 태그 라이브러리를 만들 수 있습니다.다음과 같은 것 :

class MySum {
public double sum(List list) {...}
}

귀하의 TLD에서:

<function>
<name>sum</name>
<function-class>my.MySum</function-class>
<function-signature>double sum(List)</function-signature>
</function>

JSP에는 다음과 같은 내용이 있습니다.

<%@ taglib uri="/myfunc" prefix="f" %>

${f:sum(personList)}

약간 해킹적이지만 컨트롤러 코드에서 합계가 포함된 더미 Person 개체를 만들 수 있습니다!

개체를 어떻게 검색하고 있나요?HTML을 사용하면 <TFOOT> 이 요소는 가지고 있는 모든 데이터의 맨 아래에 위치하므로 Person 개체와 별도로 합계를 설정하고 JSP 페이지에서 계산하지 않고도 페이지에 그대로 출력할 수 있습니다.

다음과 같이 JSTL을 사용하여 컬렉션을 반복할 수 있습니다.

<c:forEach items="${numList}" var="item">
      ${item}
</c:forEach>

지도라면 다음과 같이 할 수 있습니다

<c:forEach items="${numMap}" var="entry">
  ${entry.key},${entry.value}<br/>
</c:forEach>

JSP가 아닌 컨트롤러에서 합계 또는 기타 요약을 계산하는 것이 정말 바람직합니다.

JSP나 JSTL에서 너무 많은 작업을 수행하는 대신 Java 코드 및 MVC 접근 방식(예: Spring MVC 프레임워크)을 사용하세요.이러한 언어로 중요한 계산을 수행하는 것은 약하고 느리며 JSP 페이지를 훨씬 덜 명확하게 만듭니다.

예:

class PersonList_Controller implements Controller {
    ...
    protected void renderModel (List<Person> items, Map model) {
        int totalAge = 0;
        for (Person person : items) {
            totalAge += person.getAge();
        }
        model.put("items", items);
        model.put("totalAge", totalAge);
    }
}

설계 결정 측면에서 총계가 필요한 곳이라면 다음 달에 평균, 중앙값, 표준 편차를 요구하도록 확장될 수 있습니다.

JSTL 계산 및 요약은 단지 합계를 얻는 것만으로는 거의 유지되지 않습니다.정말로 JSTL의 추가 요약 요구 사항을 충족하고 싶습니까?나는 대답이 '아니요'라고 믿습니다. 따라서 올바른 설계 결정은 컨트롤러에서 동일하게/더 간단하고 확실히 더 그럴듯한 요구 사항을 확장할 수 있도록 계산하는 것입니다.

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