2015-05-22 17 views
16

Używam silnika szablonów Thymeleaf ze sprężyną i chciałbym wyświetlić tekst przechowywany za pomocą wielowierszowego tekstu.Thymeleaf + Spring: jak zachować podział linii?

W moim wielowierszowego bazie łańcucha są ze sklepu "\ n" jak ten: "Test1 \ nTest2 \ n ...."

z th: text mam: "Test1 Test2" bez linii przerwa.

Jak mogę wyświetlić podział wiersza za pomocą Thymeleaf i unikać ręcznego "\ n" zastępowania przez < br />, a następnie unikać używania th: utext (ta otwarta postać do wtrysku xss)?

Dzięki!

Odpowiedz

18

Masz dwie opcje:

  1. Wykorzystanie th: utext opcją - łatwa konfiguracja, ale trudniejsze do odczytania i zapamiętania
  2. Tworzenie procesor zwyczaj i dialekt - więcej dotyczyło konfiguracji, ale łatwiejsze, bardziej czytelne w przyszłości.

Wariant 1:

Można użyć th: utext jeśli uciec tekstu przy użyciu metody użytkową wyrażenie #strings.escapeXml(text) aby zapobiec zastrzyk XSS i niechcianych formatowania - http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#strings

Aby to niezależne od platformy , możesz użyć T(java.lang.System).getProperty('line.separator'), aby pobrać separator linii.

Korzystanie istniejące narzędzia ekspresji Thymeleaf to działa:

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

Opcja 2:

Po zakończeniu instalacji, wszystko trzeba zrobić, aby osiągnąć uciekł wyjście textLine z zachowanymi znakami końca wiersza :

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

Głównym elementem wykonującym pracę jest procesor. Poniższy kod będzie służył:

package com.davidjanney.foo.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; 
    } 


} 

Teraz, gdy masz już procesor, potrzebujesz niestandardowego dialektu, aby dodać procesor.

package com.davidjanney.foo.thymeleaf.dialects; 

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

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

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

public class DavidDialect extends AbstractDialect{ 

    public DavidDialect(){ 
     super(); 
    } 

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

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

} 

Teraz trzeba go dodać do konfiguracji XML lub Java:

Jeśli piszesz aplikację wiosny MVC, wystarczy ustawić go na własność additionalDialects fasoli Template Engine tak że jest on dodawany do dialektu domyślny SpringStandard:

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

Lub jeśli używasz wiosną i raczej używać JavaConfig można utworzyć klasę uwagami z @Configuration w pakiecie podstawowym, który zawiera dialekt jako zarządzany fasoli:

package com.davidjanney.foo; 

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

import com.davidjanney.foo.thymeleaf.dialects.DavidDialect; 

@Configuration 
public class TemplatingConfig { 

    @Bean 
    public DavidDialect davidDialect(){ 
     return new DavidDialect(); 
    } 
} 

Oto niektóre dalsze referencje dotyczące tworzenia procesorów niestandardowych oraz języka: http://www.thymeleaf.org/doc/articles/sayhelloextendingthymeleaf5minutes.html, http://www.thymeleaf.org/doc/articles/sayhelloagainextendingthymeleafevenmore5minutes.html i http://www.thymeleaf.org/doc/tutorials/2.1/extendingthymeleaf.html

+0

Idealne rozwiązanie dla mnie! Dzięki za pomoc – Chettor

+1

@Chettor Nie jestem pewien, czy Stackoverflow aktualizuje, gdy odpowiedź jest modyfikowana, czy nie, ale zawiera przykładową implementację niestandardowego procesora i podejścia dialektu. Mam nadzieję, że to pomoże! –

+0

To mi pomoże, dzięki! –

0

Spróbuj

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

To blisko idealne! Dzięki Linebreak są poprawnie wyświetlane, ALE gdy typ użytkownika uciekł znak jak "lub" to pokazać \ "lub \" (z odwrotnym ukośnikiem). Czy istnieje sposób, aby temu zapobiec? – Chettor

3

W moim przypadku escapeJava() zwraca wartości Unicode dla znaków cyrylicy, więc zawinąć wszystko w metodzie unescapeJava() pomóc rozwiązać mój problem.

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

Może nie co OP miał na myśli, ale to działa i zapobiega iniekcji kodu:

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

(z użyciem HTML5 stylu Thymeleaf.)