1

I have to display below text in thymeleaf, but it fails to display and not sure the reason and the resolution for this.

Below is the text which is coming from JSON format and I am parsing this json object and setting it in POJO Entities for Thymeleaf to render.

enter image description here

I am expecting below output:

enter image description here

If I use <span th:text="${comment.commentText}"></span>, email address displays properly but I lost formatting, meaning everything displays in one line regardless of line breaks, but if I use <span th:utext="${comment.commentText}"></span>, thymeleaf fails to render (without email address field in my commentsText, thymeleaf renders text with line breaks by using th:utext).

UPDATE:

I tried andrewJames suggested solution by replacing < and > with &lt; and &gt; It works to replace email brackets but failed to display the line breaks in thymeleaf.

Java Code:

commentData.setCommentText(comment.replaceAll("(\r\n|\r|\n|\n\r)", "<br>")
                        .replaceAll("\t", "&nbsp;&nbsp;&nbsp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;")
                );

After replace, here is my comment.getCommentText() data

  Entered comments: &lt;br&gt;&lt;br&gt;One &lt;br&gt;Two &lt;br&gt;&lt;br&gt;My Email: &lt;test@g.com&gt;

Thymeleaf code

            <span th:utext="${commentText}"></span>

and the output is:

enter image description here

I am not sure the reason why <br> tags were not rendering if I put extra lines of code at the end of my string variable replaceAll("<", "&lt;").replaceAll(">", "&gt;")

Thank you for your time and any inputs would be appreciated.

Veera
  • 369
  • 2
  • 3
  • 13
  • "_andrewJames suggested solution by replacing `<` and `>` with `<` and `>`_" - You need to replace _specific_ `<` and `>` - not all of them. You will break the HTML you want to preserve, if you replace them all. – andrewJames Mar 23 '23 at 20:52

1 Answers1

0

If the e-mail address is hard-coded, why not use:

&lt;test@g.com&gt; 

This produces the text <test@g.com>.

(no need to use Thymeleaf at all).


If the e-mail address needs to be provided by a model attribute, put it in a span - something like:

<span th:text="|&lt;${email}&gt;|"></span>

This uses |...| as a string concatenator.

You can use this <span> to get the precise layout you want.


Reference: For sequences such as &lt; see Which characters need to be escaped in HTML?


Just to add: If you don't need to use th:utext then you should avoid using it. It represents a security vulnerability, if you use it to display user-provided data (any data where you do not have full control the value being displayed).


Update

Based on the clarifications added to the question.

In this case you have a complete string. In order to use < and > to surround the e-mail address you need to do 2 things:

  1. Replace those specific < and > characters with their HTML escape codes, in the string, before passing it to Thymeleaf.

  2. Use th:utext in the Thymeleaf expression, to ensure the other HTML tags in the string (such as <br>) are processed as HTML and not as literal text.

The string becomes this:

Entered comments: <br>One <br> Two <br> My Email: &lt;test@g.com&gt;

The Thymeleaf is this:

<div th:utext="${comment.commentText}"></div>

How you perform that replacement of those two specific < and > characters is up to you - there are various possibilities.

Given you (presumably) need to parse the JSON before you can render its contents via Thymeleaf, then you can do the replacement at that point.

A Java regex replacement would be one approach:

.*(<).*(>)

You can then target those two capturing groups at the end of the string - the (<) and (>) - and replace them with their HTML escape sequences.

But none of that relevant code is shown in the question, so this is speculation.

I would recommend asking a new, specific, focused question for that new, specific step if the solution is not obvious (I say this because it significantly changes the question you originally asked here - and therefore should be a new question.)


Perhaps this will point you in one possible direction (I am sure there are many other approaches which could also work):

final String string = "Entered comments: <br>One <br> Two <br> My Email: <test@g.com>";
// separates the final < and > characters (creates 4 groups overall):
final String regex = "(.*)(<)(.*)(>)";
// replaces group $2 (final <) and group $4 (final >) with the HTML escape characters:
final String subst = "$1&lt;$3&gt;";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);
final String result = matcher.replaceAll(subst);
// result: "Entered comments: <br>One <br> Two <br> My Email: &lt;test@g.com&gt;"
System.out.println(result);
andrewJames
  • 19,570
  • 8
  • 19
  • 51
  • Thanks AndrewJames. However, above text is in JSON format and want to display it in thymeleaf. It's not hardcoded or Individual model attribute. – Veera Mar 22 '23 at 20:28
  • Can you explain (by editing your question) what you mean by the data being "in JSON format"? There is no mention of JSON in your question (and no mention of it in my answer) - so I am not sure what you mean, here. – andrewJames Mar 22 '23 at 21:16
  • 1
    I have edited question for more readability – Veera Mar 23 '23 at 17:35
  • OK - thank you - now I understand the situation. I have updated my answer. – andrewJames Mar 23 '23 at 18:07
  • Thanks AndrewJames. I tried your solution and updated my question with further details. – Veera Mar 23 '23 at 20:42
  • Take a closer look at my answer: You need to replace _those two specific `<` and `>` characters_ - the ones surrounding the e-mail address. Look at the string following my note _The string becomes this_ (and it shows which characters are _not_ replaced). Look at my regex `.*(<).*(>)` which selects the _final_ two `<` and `>` characters - not any of the others. – andrewJames Mar 23 '23 at 20:44