【问题标题】:Thymeleaf iterating a Java 8 Stream from Spring Data JPAThymeleaf 从 Spring Data JPA 迭代 Java 8 流
【发布时间】:2017-01-11 15:27:17
【问题描述】:

我的 Google-Fu 让我失望了,所以我问你...有没有办法用 Thymeleaf 迭代 Java 8 流,类似于迭代 List 的方式,同时仍然保持 Stream 的性能目的?

存储库

Stream<User> findAll()

型号

Stream<User> users = userRepository.findAll();
model.addAttribute("users", users);

查看

<div th:each="u: ${users}">
   <div th:text="${u.name}">

如果我尝试这个,我会得到:

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'name' cannot be found on object of type 'java.util.stream.ReferencePipeline$Head' - maybe not public?

如果我改用列表,它会按预期工作。

有没有合适的方法来处理我找不到的流?

【问题讨论】:

  • 我也看不到。如您所述,您可以转换为列表:List&lt;User&gt; result = users.collect(Collectors.toList());

标签: java spring spring-data-jpa thymeleaf spring-el


【解决方案1】:

虽然 Thymeleaf 不支持 documentation 中的流,但它确实支持 Iterable,因此您可以执行以下操作:

型号:

Stream<User> users = userRepository.findAll();
model.addAttribute("users", (Iterable<User>) users::iterator);

您的视图将按照您已经编写的那样工作:

<div th:each="u: ${users}">
    <div th:text="${u.name}">

查看版本 3 documentation,它表示它将支持任何实现 Iterator 的对象,因此也应该可以这样做:

型号:

Stream<User> users = userRepository.findAll();
model.addAttribute("users", users.iterator());

我没有使用那个版本,所以我无法让它工作。

【讨论】:

    【解决方案2】:

    据我所知并查看 Thymeleaf documentation 没有办法做你想做的事。

    除了 Thymeleaf 不提供任何与流交互的方式之外,请注意 Stream 对象在您执行终端操作之前无法访问其包含的对象(例如 Collectors.toList()

    【讨论】:

      【解决方案3】:

      这个帖子有点旧,但我没有看到任何更新的帖子。它可以用正确的秘方来完成。

      在Java代码中,你必须做三件事:

      1. 使用@javax.transaction.Transactional 注释
      2. 手动调用 Thymeleaf 处理模板
      3. 在模板处理中使用 try-with-resources 块来保证流已关闭

      在您的模板中,如果您传递 Stream 的迭代器,您不必做任何不同的事情,因为 Thyemeleaf 已经了解迭代器。

      从 Spring Data 返回流时需要 @Transactional 注解。关键是带注释的方法必须在流结束之前实际使用流 - 使用 Thyemleaf 不会发生这种情况,方法只是返回字符串模板名称的“正常”方式。

      同时,流已关闭(当您使用流来执行诸如将列表转换为地图之类的操作时,您不必这样做)。通过自己控制模板生成过程,您可以确保在您的 @Transactional 方法中关闭和使用流。

      Java 代码如下所示(我使用的是 Spring 5 MVC):

      @Controller
      public class CustomerController {
          @Autowired
          SpringTemplateEngine templateEngine;
      
          @Autowired
          private CustomerRepository customerRepository;
      
          @RequestMapping("/customers")
          @Transactional
          public void customers(
              final String firstName,
              final HttpServletRequest request,
              final HttpServletResponse response
          ) throws IOException {
              final WebContext ctx = new WebContext(
                  request,
                  response,
                  request.getServletContext(),
                  request.getLocale()
              );
      
              try (
                  final Stream<CustomerModelEntity> models = 
                      (firstName == null) || firstName.isEmpty() ?
                      customerRepository.findAll() :
                      customerRepository.findByFirstNameIgnoringCaseOrderByLastNameAscFirstNameAsc(firstName)
              ) {
                  ctx.setVariable(
                      "customers",
                      models.iterator()
                  );
      
                  response.setContentType("text/html");
      
                  templateEngine.process(
                      "customer-search",
                      ctx,
                      response.getWriter()
                  );
              }
          }
      }
      

      Thymeleaf 模板如下(我使用的是解耦逻辑):

      <?xml version="1.0"?>
      <thlogic>
        <attr sel=".results" th:remove="all-but-first">
          <attr sel="/.row[0]" th:each="customer : ${customers}">
            <attr sel=".first-name" th:text="${customer.firstName}" />
            <attr sel=".middle-name" th:text="${customer.middleName}" />
            <attr sel=".last-name" th:text="${customer.lastName}" />
          </attr>
        </attr>
      </thlogic>
      

      【讨论】:

        猜你喜欢
        • 2015-07-30
        • 2017-03-16
        • 1970-01-01
        • 2015-02-28
        • 2018-02-12
        • 2016-08-12
        • 2015-05-31
        • 1970-01-01
        • 2015-02-11
        相关资源
        最近更新 更多