我的Google-Fu让我失望了,所以我问你.是否有一种方法可以使用Thymeleaf迭代Java 8流,就像迭代列表时仍然保持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?
如果我使用了一个列表,它就会像预期的那样工作。
有没有合适的方法来处理我找不到的流?
发布于 2017-01-11 17:09:37
据我所知,看看Thymeleaf 文档,没有办法做你想做的事。
除了Thymeleaf不提供与流交互的任何方式之外,还要考虑到Stream
对象在执行终端操作之前无法访问其包含的对象(例如,Collectors.toList()
)。
发布于 2018-08-01 18:14:27
这篇文章有点旧,但我没有看到任何更新的。这可以用正确的秘方来做。
在Java代码中,您必须做三件事:
在模板中,如果您传递Stream的迭代器,您不需要做任何不同的事情,因为Thyemeleaf已经理解迭代器了。
从Spring数据返回流时,需要使用@Transactional注释。关键是,带注释的方法必须在流结束之前实际使用它--这不会发生在使用Thyemleaf时,即方法返回字符串模板名的“正常”方式。
同时,流已经关闭(在使用流执行诸如将列表转换为Map之类的工作时,不必这样做)。通过自己控制模板生成过程,可以确保流在@Transactional方法中被关闭和使用。
Java代码如下所示(我正在使用Spring5MVC):
@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>
https://stackoverflow.com/questions/41594709
复制相似问题