java Thymeleaf:用 <br> 替换换行符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30655011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:27:16  来源:igfitidea点击:

Thymeleaf: replace newline characters with <br>

javaspringspring-mvcthymeleaf

提问by dominik

I have a field (<textarea name="desc" />) that may contain newlines and I want to replace them with their HTML counterpart: <br />. How can I do this? I'm using Thymeleaf 2.1.4.RELEASE.

我有一个字段 ( <textarea name="desc" />) 可能包含换行符,我想用对应的 HTML 替换它们:<br />. 我怎样才能做到这一点?我正在使用 Thymeleaf 2.1.4.RELEASE。

采纳答案by dominik

As in JSP, it's not possible to use simple and straightforward

就像在 JSP 中一样,不可能使用简单直接的

${#strings.replace(desc, '\n', '<br />')}

There are at least two problems:

至少有两个问题:

  • '\n' is treated by underlying expression language (SpEL in my case as I'm using Spring MVC) as string literal that consist of two separate characters: '\' and 'n' rather than single newline character
  • exception is being thrown as the Thymeleaf underlying XML parser does not allow to put <and >inside expressions
  • '\n' 被底层表达式语言(在我的例子中是 SpEL,因为我使用 Spring MVC)作为由两个单独字符组成的字符串文字处理:'\' 和 'n' 而不是单个换行符
  • 正在抛出异常,因为 Thymeleaf 底层 XML 解析器不允许放置<>内部表达式

The solution I found for the first problem is to set newline character in a controller and pass it to view.

我为第一个问题找到的解决方案是在控制器中设置换行符并将其传递给视图。

To address the second problem you need to use &lt;instead of <and &gt;instead of >. Also remember that this implies using th:utextinstead of th:text

要解决第二个问题,您需要使用&lt;代替<&gt;代替>。还要记住,这意味着使用th:utext而不是th:text

// in controller:
model.addAttribute("newLineChar", '\n');

// in view
${#strings.replace(desc, newLineChar, '&lt;br /&gt;')}

If you are using Thymeleaf + Spring (what means that Thymeleaf will use SpEL instead of OGNL), you may also use SpEL T operator.This way you don't have to declare the newline variable in your controller but mind out that newline separator in this case will vary across operating systems that your app is running on:

如果您使用的是 Thymeleaf + Spring(这意味着 Thymeleaf 将使用 SpEL 而不是 OGNL),您也可以使用 SpEL T operator。这样您就不必在控制器中声明换行符,但在这种情况下请注意换行符将因您的应用程序运行的操作系统而异:

${#strings.replace(desc, T(System).getProperty('line.separator'), '&lt;br /&gt;')}

What I'm going to finally use is the combination of the above + Apache StringUtils that defines public static final String LF = "\n";:

我最终要使用的是上述 + Apache StringUtils 的组合,它定义了public static final String LF = "\n";

${#strings.replace(desc, T(org.apache.commons.lang3.StringUtils).LF, '&lt;br /&gt;')}

回答by holmis83

As stated by dominik, \nfor newline does not work. However, you can use &#10;.

正如dominik 所述\n换行符不起作用。但是,您可以使用&#10;.

${#strings.replace(desc,'&#10;','&lt;br&gt;')}

Or with escaping to prevent code injection:

或者通过转义来防止代码注入:

${#strings.replace(#strings.escapeXml(desc),'&#10;','&lt;br&gt;')}

回答by ashurexm

It's possible to do this with a custom dialect and attribute processor to handle doing this without a lot of inline SpEl or hacks.

可以使用自定义方言和属性处理器来完成此操作,无需大量内联 SpEl 或 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);
        return StringUtils.replace(value, "\n", "<br />");
    }

    @Override
    public int getPrecedence()
    {
        return 10000;
    }
}

You have to extend the AbstractUnescapedTextChildModifierAttrProcessorprocessor or else you'll get the html entity tags for <br />and you won't actually get a line break.

您必须扩展AbstractUnescapedTextChildModifierAttrProcessor处理器,否则您将获得 html 实体标签,<br />而您实际上不会获得换行符。

Creating a custom dialect

创建自定义方言

To implement a custom dialect you need a dialect class like so:

要实现自定义方言,您需要一个像这样的方言类:

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 getPrefixmethod return value is what you would use to call any custom processors that you make. For example, Thymeleaf uses th. The custom processor we implemented above this is looking for nl2brso to call it you would use the cd:nl2brattribute instead of th:text.

getPrefix方法的返回值是你会用什么来调用任何定制处理器,你做。例如,Thymeleaf 使用th. 我们在上面实现的自定义处理器正在寻找,nl2br因此要调用它,您将使用cd:nl2br属性而不是th:text.

Registering your new dialect

注册您的新方言

In your main class, you just need to create a @Beanthat will return a new instance of your dialect class.

在你的主类中,你只需要创建一个@Bean将返回你方言类的新实例。

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Bean
    public MyCustomDialect myCustomDialect()
    {
        return new MyCustomDialect();
    }
}

Using your custom processor

使用您的自定义处理器

Finally, in your template file you would have an HTML tag like this:

最后,在你的模板文件中,你会有一个像这样的 HTML 标签:

<div cd:nl2br="${myObject.myField}">MY MULTILINE FIELD</div>

<div cd:nl2br="${myObject.myField}">MY MULTILINE FIELD</div>

For a more thorough guide to implementing custom dialects I recommend the Thymeleaf docs:

有关实施自定义方言的更全面指南,我推荐 Thymeleaf 文档: