2

我正在尝试将Thymeleafview 与Scala. 我有User一个包含电子邮件集合的实体,我想在 Thymeleaf 模板中访问这些电子邮件:

在 User.scala 中

case class User (@BeanProperty val emails: scala.immutable.List[String])

在一些百里香模板.html

<div th:text="${user.emails[0]}">...</div>

问题是 Spring 表达式求值器(Thymeleaf 将表达式求值作业委托给它)只理解 Java 集合类型,因此尝试获取[0]Scala 列表 ( ) 的第一个元素 ( user.emails) 失败并出现异常。

我试图深入研究 SpEL 源代码,以找到一个可以添加 Java 到 Scala 转换的地方。似乎如果我可以拦截对该方法的调用org.springframework.expression.PropertyAccessor.read(..)并在从该方法返回时执行转换,它可能会起作用。

但我找不到拦截这些电话的方法。我考虑过用代理包装这些属性访问器实例,但是它们的初始化代码被硬编码到 ThymeleafSpelExpressionEvaluator和类中SpelVariableExpressionEvaluatorSpelEvaluationContext'因此我没有明显的地方可以放置我的包装器。

是否有任何或多或少优雅的方式来包装 Thymeleaf 中使用的属性访问器(或更一般地向 Thymeleaf 和/或 SpEL 添加 Scala 集合支持)而不重写太多 Thymeleaf 和 SpEL 胆量?

先感谢您!

4

1 回答 1

1

您可以删除 @BeanProperty,并为互操作性添加一个 getter:

case class User(emails: List[String]) {
  def getEmails = JavaConversions.asJavaIterable(emails)
}

更优雅的是使用Scala EL 解析器

更新

至于解析器:在 Thymeleaf/SpringEL 的某个地方,表达式解析器解析 bean 的属性:所以在你的例子中:

${user.emails[0]}

getEmails它可能使用反射来查看对象中是否有 getter 方法user。在这里,您可以添加与链接的 Scala EL 解析器中相同的代码:如果 getter 返回一个Scala 集合,则将其包装在Java 可迭代对象中(或将其转换为数组)。

于 2013-07-05T12:43:36.410 回答