Thymeleaf + Spring:如何保持断线?

时间:2015-05-22 10:32:36

标签: spring thymeleaf spring-el

我在春天使用Thymeleaf模板引擎,我希望显示通过多行文本区域存储的文本。

在我的数据库中,多行字符串存储为" \ n"像这样:" Test1 \ nTest2 \ n ......"

用th:text得到:" Test1 Test2"没有换行。

如何使用Thymeleaf显示换行符并避免手动" \ n"用&替换BR />然后避免使用th:utext(这个开放形式到xss注入)?

谢谢!

7 个答案:

答案 0 :(得分:22)

您有两个选择:

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

    如果使用表达式实用程序方法#strings.escapeXml( text )转义文本以防止XSS注入和不需要的格式化,则可以使用th:utext - 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

答案 1 :(得分:6)

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

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

(使用HTML5风格的Thymeleaf。)

答案 2 :(得分:5)

在我的情况下,escapeJava()返回西里尔符号的unicode值,因此我将所有内容包装在unescapeJava()方法帮助中以解决我的问题。

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

答案 3 :(得分:1)

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

例如:

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

如果可能,请避免使用th:utext,因为这会严重影响安全性。如果不小心,th:utext可能会造成XSS攻击。

答案 4 :(得分:0)

试试这个

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

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:0)

如果您在thymleaf中使用jQuery,则可以使用以下格式设置代码:

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

希望答案能为您提供帮助