I originally posted this answer to a previous SO question , but this one seems to pop up too. I changed it to display the table instead of newlines.
This can be done using a special dialect and an attribute processor to handle this without a lot of built-in SpEl or hacks.
Creating a custom attribute processor
public class NewlineAttrProcessor extends AbstractUnescapedTextChildModifierAttrProcessor { public NewlineAttrProcessor() { super("nl2br"); } @Override protected String getText(Arguments arguments, Element element, String attributeName) { final Configuration configuration = arguments.getConfiguration(); final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration); final String attributeValue = element.getAttributeValue(attributeName); final IStandardExpression expression = parser.parseExpression(configuration, arguments, attributeValue); final String value = (String)expression.execute(configuration, arguments); final String[] lines = StringUtils.split(value, "\n"); return "<table><td>" + StringUtils.join(lines, "</td><td>") + "</td></table>"; } @Override public int getPrecedence() { return 10000; } }
You need to extend the AbstractUnescapedTextChildModifierAttrProcessor processor, otherwise you will get html entity tags for <table>...</table> and you will not actually get HTML.
Create custom dialect
To implement a custom dialect, you will need a dialect class:
public class MyCustomDialect extends AbstractDialect { @Override public String getPrefix() { return "cd"; } @Override public Set<IProcessor> getProcessors() { final Set<IProcessor> processors = new HashSet<>(); processors.add(new NewlineAttrProcessor()); return processors; } }
The return value of the getPrefix method is what you could use to call any custom processors you make. For example, Thimeleaf uses th . The user processor that we implemented above this is looking for nl2br , so you must use the cd:nl2br instead of th:text to call it.
Register a new dialect
In your main class, you just need to create @Bean , which will return a new instance of your dialect class.
@SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } @Bean public MyCustomDialect myCustomDialect() { return new MyCustomDialect(); } }
Using a custom processor
Finally, in your template file you will have the following HTML tag:
<div cd:nl2br="${myObject.myField}">MY MULTILINE FIELD</div>
For a more detailed guide on implementing custom dialects, I recommend the Thymeleaf docs: