Thymeleaf + Spring:如何保持断线?

问题描述 投票:21回答:6

我正在使用带弹簧的Thymeleaf模板引擎,我想显示通过多行textarea存储的文本。

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

用th:text得到了:“Test1 Test2”没有换行符。

如何使用Thymeleaf显示换行符并避免手动“\ n”替换为<br />然后避免使用th:utext(这种开放形式到xss注入)?

谢谢 !

spring thymeleaf spring-el
6个回答
22
投票

你有两个选择:

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

选项1:

你可以使用th:utext,如果你使用表达式实用程序方法#strings.escapeXml( text )来逃避文本,以防止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应用程序,则只需将其设置为Template Engine bean的additionalDialects属性,以便将其添加到默认的SpringStandard方言中:

    <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,则可以在基础包中创建一个使用@Configuration注释的类,该类包含方言作为托管bean:

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.htmlhttp://www.thymeleaf.org/doc/articles/sayhelloagainextendingthymeleafevenmore5minutes.htmlhttp://www.thymeleaf.org/doc/tutorials/2.1/extendingthymeleaf.html


6
投票

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

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

(使用HTML5风格的Thymeleaf。)


5
投票

在我的情况下,escapeJava()返回西里尔符号的unicode值,所以我用unescapeJava()方法帮助解决我的问题。

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

0
投票

试试这个

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

0
投票

你需要使用th:utext并将break行追加到string。我的代码是:

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

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

0
投票

如果您在百万美元中使用jQuery,可以使用以下格式设置代码格式:

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

希望答案可以帮到你

© www.soinside.com 2019 - 2024. All rights reserved.