Подтвердить что ты не робот

Рассчитать общую сумму всех чисел в цикле c: forEach

У меня есть Java bean, как это:

class Person {
  int age;
  String name;
}

Я хотел бы перебрать коллекцию этих beans в JSP, показывая каждого человека в строке таблицы HTML, а в последней строке таблицы я хотел бы показать общее количество всех возрастов.

Код для создания строк таблицы будет выглядеть примерно так:

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

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

4b9b3361

Ответ 1

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

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

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

Решение Pure 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

Другой способ вывода итогов без ввода кода сценария в ваш 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}"/>

Дисплей

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

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

Ответ 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}

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

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

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

Ответ 7

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

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