首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Thymeleaf从Spring数据JPA迭代Java 8流

Thymeleaf从Spring数据JPA迭代Java 8流
EN

Stack Overflow用户
提问于 2017-01-11 15:27:17
回答 2查看 4.2K关注 0票数 2

我的Google-Fu让我失望了,所以我问你.是否有一种方法可以使用Thymeleaf迭代Java 8流,就像迭代列表时仍然保持Stream的性能目标一样?

存储库

代码语言:javascript
运行
复制
Stream<User> findAll()

模型

代码语言:javascript
运行
复制
Stream<User> users = userRepository.findAll();
model.addAttribute("users", users);

视图

代码语言:javascript
运行
复制
<div th:each="u: ${users}">
   <div th:text="${u.name}">

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

代码语言:javascript
运行
复制
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?

如果我使用了一个列表,它就会像预期的那样工作。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-11 17:09:37

据我所知,看看Thymeleaf 文档,没有办法做你想做的事。

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

票数 2
EN

Stack Overflow用户

发布于 2018-08-01 18:14:27

这篇文章有点旧,但我没有看到任何更新的。这可以用正确的秘方来做。

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

  1. 使用@javax.transaction.Transactional注释
  2. 手动调用Thymeleaf来处理模板
  3. 在模板处理中使用“尝试资源”块,以确保流已关闭。

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

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

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

Java代码如下所示(我正在使用Spring5MVC):

代码语言:javascript
运行
复制
@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模板如下(我使用的是解耦逻辑):

代码语言:javascript
运行
复制
<?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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41594709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档