Frage

I am trying to use Thymeleaf view in conjunction with Scala. I have User entity with a collection of emails and I want to access those emails in Thymeleaf template:

in User.scala

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

in some-thymeleaf-template.html

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

The problem is that Spring expression evaluator (to which Thymeleaf delegates the expression evaluation job) only understands Java collection types and thus the attempt to take the 1st element ([0]) of the Scala list (user.emails) fails with an exception.

I tried to dig into the SpEL source code to find a place where I can possibly add a Java-to-Scala conversion. And it seems like if I could intercept the call to the org.springframework.expression.PropertyAccessor.read(..) method and perform the conversions on the returning from the method it would probably work.

But I couldn't find a way how to intercept those calls. I thought about wrapping those property accessor instances with a proxy, but their initialization code is hardcoded into Thymeleaf's SpelExpressionEvaluator, SpelVariableExpressionEvaluator and SpelEvaluationContext'classes, so that there is no obvious place for me to put my wrapper in.

Is there any more or less elegant way to wrap the property accessors used in Thymeleaf (or more generally add Scala collections support to Thymeleaf and/or SpEL) without rewriting too much Thymeleaf and SpEL guts?

Thank you in advance!

War es hilfreich?

Lösung

You could remove @BeanProperty, and add a getter for Interoperability:

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

Far more elegant is to use a Scala EL resolver

Update

As for the resolver: Somewhere in Thymeleaf/SpringEL, an expression parser resolves properties of beans: So in your example:

${user.emails[0]}

it possibly uses reflection to see if there is a getter method getEmails in the user object. This is the place where you could add the same code as in the linked Scala EL resolver: If the getter returns a Scala collection, wrap it in a Java iterable (or convert it to an array) before.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top