2008-09-19 10 views
16

У меня есть Java-компонент, как это:Вычислить общую сумму всех чисел в C: Foreach петля

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> 

Однако, я изо всех сил, чтобы найти способ, чтобы вычислить возраст всего, что будет показано в заключительной строке , не прибегая код сценария, любые предложения?

+0

Вы складываете все возрасты и показываете это в последней строке? – ScArcher2 2008-09-19 15:45:08

ответ

36

Примечание: Я пытался комбинируя ответы, чтобы сделать полный список. Я упоминал имена, где это уместно, чтобы давать кредит там, где это необходимо.

Есть много способов решить эту проблему, с плюсы/минусы, связанные с каждым:

Pure 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 становится запутанным до точки, где вы могли бы также иметь я ntroduced scripsts. Если вы ожидаете, что все, кто смотрит на страницу, смогут следить за рудиментарной логикой, это прекрасный выбор.

Чистый раствор EL

Если вы уже на EL 3.0 (Java EE 7/Servlet 3.1), использовать новую поддержку streams and lambdas:

<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 Функции

Другой способ вывода итоговой суммы без ввода кода scriplet в ваш JSP - это использование функции EL. Функции EL позволяют вам вызывать открытый статический метод в открытом классе. Например, если вы хотите перебрать свою коллекцию и суммировать значения, вы можете определить публичный статический метод sum (List people) в публичном классе, возможно, называемый PersonUtils. В файле 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 Функции имеют несколько преимуществ. Они позволяют использовать существующие методы 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> 

Объяви TagLib на в верхней части вашего JSP:

<%@ 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}"/> 

Display Tag

Как уже упоминалось ранее ZMF, вы можете также использовать дисплей тег, хотя вам нужно будет включать соответствующие библиотеки:

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

0

Это немного взломанный, но в вашем коде контроллера вы можете просто создать фиктивный объект Person с общим количеством в нем!

Как вы восстанавливаете свои объекты? HTML позволяет вам установить элемент <TFOOT>, который будет располагаться внизу всех данных, поэтому вы можете просто установить общее количество отдельно от объектов Person и вывести его на странице как есть без каких-либо вычислений на странице JSP.

3

Вы пытаетесь сложить все возрасты?

Вы можете вычислить его в своем контроллере и отобразить только результат в jsp.

Вы можете написать собственный тег для расчета.

Вы можете рассчитать его в jsp, используя jstl, как это.

<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} 
1

ScArcher2 имеет простейший solution. Если вам нужно что-то максимально компактное, вы можете создать библиотеку тегов с функцией «sum». Что-то вроде:

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

В вашем домене:

<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)} 
+0

Не универсальный - какое свойство или функция-результат sum() предназначен для вычисления, не может быть указан. Либо вы прошли долгий путь, чтобы сделать одноцелевой оператор, либо вам нужно идти дальше и взломать отражение, чтобы сделать его универсальным. – 2013-03-30 05:47:40

+0

Короткий и правильный ответ: вычислить сводку в контроллере, а не в JSP. – 2013-03-30 05:48:01

0

вы можете перебирать над сборкой, использующей JSTL в соответствии со следующими

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

если это карта вы можете сделать на следующем

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

Вычисления итогов/или других резюме в контроллере - не в JSP - это действительно сильно предпочтительнее.

Используйте Java-код & подход MVC, например Spring Framework MVC, вместо того, чтобы пытаться сделать слишком много в JSP или JSTL; выполнение значительных вычислений на этих языках является слабым & медленным, и делает ваши страницы 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? Я считаю, что ответ НЕТ - и поэтому правильное дизайнерское решение должно рассчитывать в Контроллере, так же как и все более простые и определенно более правдоподобные требования.

 Смежные вопросы

  • Нет связанных вопросов^_^