Thymeleaf + Spring :如何保持换行?

Thymeleaf + Spring : How to keep line break?

我将 Thymeleaf 模板引擎与 spring 一起使用,我想显示通过多行文本区域存储的文本。

在我的数据库中,多行字符串存储为“\n”,如下所示:"Test1\nTest2\n...."

有了 th:text 我得到了:"Test1 Test2" 没有换行符。

我如何使用 Thymeleaf 显示换行符并避免手动将“\n”替换为
然后避免使用 th:utext(这种打开 xss 注入的形式)?

谢谢!

试试这个

<p th:utext="${#strings.replace(#strings.escapeJava(description),'\n','&lt;br /&gt;')}" ></p>

你的两个选择:

  1. 使用 th:utext - 简单的设置选项,但更难阅读和记忆
  2. 创建自定义处理器和方言 - 设置更复杂,但将来使用起来更容易、更具可读性。

选项 1:

如果使用表达式实用程序方法 #strings.escapeXml( text ) 转义文本,则可以使用 th:utext 以防止 XSS 注入和不需要的格式 - http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#strings

要让这个平台独立,可以使用T(java.lang.System).getProperty('line.separator')来抓取行分隔符。

使用现有的 Thymeleaf 表达式实用程序,这有效:

<p th:utext="${#strings.replace( #strings.escapeXml( text ),T(java.lang.System).getProperty('line.separator'),'&lt;br /&gt;')}" ></p>

选项 2:

这个API现在在3中有所不同(我为2.1写了这个教程) 希望您可以将以下逻辑与他们的官方教程结合起来。也许有一天我会有一分钟的时间来完全更新它。但现在: Here's the official Thymeleaf tutorial for creating your own dialect.

设置完成后,您需要做的就是完成保留换行符的转义文本行输出:

<p fd:lstext="${ text }"></p>

完成这项工作的主要部分是处理器。以下代码可以解决问题:

package com.foo.bar.thymeleaf.processors 

import java.util.Collections;
import java.util.List;

import org.thymeleaf.Arguments;
import org.thymeleaf.Configuration;
import org.thymeleaf.dom.Element;
import org.thymeleaf.dom.Node;
import org.thymeleaf.dom.Text;
import org.thymeleaf.processor.attr.AbstractChildrenModifierAttrProcessor;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.unbescape.html.HtmlEscape;

public class HtmlEscapedWithLineSeparatorsProcessor extends
        AbstractChildrenModifierAttrProcessor{

    public HtmlEscapedWithLineSeparatorsProcessor(){
        //only executes this processor for the attribute 'lstext'
        super("lstext");
    }

    protected String getText( final Arguments arguments, final Element element,
            final 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);

        //return the escaped text with the line separator replaced with <br />
        return HtmlEscape.escapeHtml4Xml( value ).replace( System.getProperty("line.separator"), "<br />" );


    }



    @Override
    protected final List<Node> getModifiedChildren(
            final Arguments arguments, final Element element, final String attributeName) {

        final String text = getText(arguments, element, attributeName);
        //Create new text node signifying that content is already escaped.
        final Text newNode = new Text(text == null? "" : text, null, null, true);
        // Setting this allows avoiding text inliners processing already generated text,
        // which in turn avoids code injection.
        newNode.setProcessable( false );

        return Collections.singletonList((Node)newNode);


    }

    @Override
    public int getPrecedence() {
        // A value of 10000 is higher than any attribute in the SpringStandard dialect. So this attribute will execute after all other attributes from that dialect, if in the same tag.
        return 11400;
    }


}

现在你有了处理器,你需要一个自定义方言来添加处理器。

package com.foo.bar.thymeleaf.dialects;

import java.util.HashSet;
import java.util.Set;

import org.thymeleaf.dialect.AbstractDialect;
import org.thymeleaf.processor.IProcessor;

import com.foo.bar.thymeleaf.processors.HtmlEscapedWithLineSeparatorsProcessor;

public class FooDialect extends AbstractDialect{

    public FooDialect(){
        super();
    }

    //This is what all the dialect's attributes/tags will start with. So like.. fd:lstext="Hi David!<br />This is so much easier..."
    public String getPrefix(){
        return "fd";
    }

    //The processors.
    @Override
    public Set<IProcessor> getProcessors(){
        final Set<IProcessor> processors = new HashSet<IProcessor>();
        processors.add( new HtmlEscapedWithLineSeparatorsProcessor() );
        return processors;
    }

}

现在您需要将它添加到您的 xml 或 java 配置中:

如果您正在编写 Spring MVC 应用程序,您只需在模板引擎 bean 的 additionalDialects 属性 中设置它,以便将其添加到默认 Spring标准方言:

    <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
  <property name="templateResolver" ref="templateResolver" />
  <property name="additionalDialects">
    <set>
      <bean class="com.foo.bar.thymeleaf.dialects.FooDialect"/>
    </set>
  </property>
    </bean>

或者,如果您正在使用 Spring 并且宁愿使用 JavaConfig,您可以在包含方言作为托管 bean 的基础包中创建一个带有 @Configuration 注释的 class:

package com.foo.bar;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.foo.bar.thymeleaf.dialects.FooDialect;

@Configuration
public class TemplatingConfig {

    @Bean
    public FooDialect fooDialect(){
        return new FooDialect();
    }
}

这里有一些关于创建自定义处理器和方言的进一步参考:http://www.thymeleaf.org/doc/articles/sayhelloextendingthymeleaf5minutes.html , http://www.thymeleaf.org/doc/articles/sayhelloagainextendingthymeleafevenmore5minutes.html and http://www.thymeleaf.org/doc/tutorials/2.1/extendingthymeleaf.html

在我的例子中 escapeJava() returns 西里尔符号的 unicode 值,所以我将所有内容包装在 unescapeJava() 方法中有助于解决我的问题。

<div class="text" th:utext="${#strings.unescapeJava(#strings.replace(#strings.escapeJava(comment.text),'\n','&lt;br /&gt;'))}"></div>

也许不是 OP 的初衷,但这可以防止代码注入:

<p data-th-utext="${#strings.replace(#strings.escapeXml(text),'&#10;','&lt;br&gt;')}"></p>

(使用 HTML5 风格的 Thymeleaf。)

您需要使用 th:utext 并将换行符附加到字符串。 我的代码是:

StringBuilder message = new StringBuilder();
        message.append("some text");
        message.append("<br>");
        message.append("some text");

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

如果您在 thymeleaf 中使用 jQuery,您可以使用以下格式格式化您的代码:

$('#idyourdiv').val().replace(/\n\r?/g, '<br />')

希望回答对您有所帮助

尝试将 style="white-space: pre-line" 放在元素上。

例如:

<span style="white-space: pre-line" th:text="${text}"></span>

您可能还对 white-space: pre-wrap 感兴趣,它除了换行符外还保持连续的空格。

尽可能避免使用 th:utext,因为它具有严重的安全隐患。如果不注意,th:utext 可能会造成 XSS 攻击。

受@DavidRoberts 回答的启发,我制作了一个 Thymeleaf 方言,如果 css white-space 属性 不是一个选项,它可以很容易地保留换行符。 如果需要,它还可以支持 BBCode。 您可以将它作为依赖项导入(它非常轻便,并且由于启动项目而非常容易设置),或者只是将它作为灵感来制作您自己的。 在这里查看: https://github.com/oxayotl/meikik-project