2015-05-22 8 views
16

Sto usando il motore di template di Thymeleaf con spring e mi piacerebbe visualizzare il testo memorizzato in una textarea multilinea.Thymeleaf + Spring: come mantenere un'interruzione di linea?

Nella mia stringa di database su più righe sono negozio con "\ n" in questo modo: "Test1 \ nTest2 \ n ...."

Con th: testo ho: "Test1 Test2" con nessuna linea rompere.

Come posso visualizzare un'interruzione di riga utilizzando Thymeleaf ed evitare manualmente "\ n" sostituendo con < br /> e quindi evitare di utilizzare th: utext (questo modulo aperto per l'iniezione xss)?

Grazie!

risposta

18

si hanno due opzioni:

  1. Uso th: utext - opzione di installazione facile, ma più difficile da leggere e ricordare
  2. Creare un processore personalizzato e il dialetto - altro installazione implicata, ma un uso futuro più facile e più leggibile.

Opzione 1:

È possibile utilizzare th: utext se a fuggire il testo utilizzando il metodo di utilità espressione #strings.escapeXml(text) per evitare l'iniezione XSS e la formattazione indesiderati - http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#strings

Per rendere questa piattaforma indipendente , è possibile utilizzare T(java.lang.System).getProperty('line.separator') per afferrare il separatore di riga.

Utilizzo delle utilità di espressione Thymeleaf esistenti, questo funziona:

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

Opzione 2:

Una volta che l'installazione è completa, tutto ciò che sarà necessario fare per raggiungere l'uscita TextLine fuggito con interruzioni di riga conservati :

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

Il pezzo principale che fa il lavoro è il processore. Il seguente codice farà il trucco:

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; 
    } 


} 

Ora che si dispone del processore, è necessario un dialetto personalizzato per aggiungere il processore.

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; 
    } 

} 

Ora è necessario aggiungere al tuo xml o Java configurazione:

Se si scrive un'applicazione Spring MVC, basta impostarlo alla proprietà additionalDialects del fagiolo Template Engine, così che si aggiunge al dialetto di default 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> 

Oppure, se si utilizza la primavera e preferisce utilizzare JavaConfig è possibile creare una classe annotato con @Configuration nel pacchetto base che contiene il dialetto come un bean gestito:

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(); 
    } 
} 

Ecco alcuni ulteriori riferimenti sulla creazione di processori personalizzati e dialetti: http://www.thymeleaf.org/doc/articles/sayhelloextendingthymeleaf5minutes.html, http://www.thymeleaf.org/doc/articles/sayhelloagainextendingthymeleafevenmore5minutes.html e http://www.thymeleaf.org/doc/tutorials/2.1/extendingthymeleaf.html

+0

Soluzione perfetta per me! Grazie per il tuo aiuto – Chettor

+1

@Chettor Non sono sicuro se StackOverflow ti aggiorna quando la risposta è stata modificata o meno, ma ho incluso un'implementazione di esempio per il processore personalizzato e l'approccio dialettale. Spero che sia d'aiuto! –

+0

Mi aiuterà, grazie! –

0

Prova questo

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

E 'quasi perfetto! Grazie Linebreak sono visualizzati correttamente MA quando il tipo di carattere di escape come "o" mostra \ "o \ '(con barra rovesciata). C'è un modo per impedirlo? – Chettor

3

Nel mio caso escapeJava() restituisce i valori Unicode per i simboli cirillici, quindi avvolgere il tutto in unescapeJava() metodo di aiuto per risolvere il mio problema.

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

Forse non quello che il PO aveva in mente, ma questo funziona e impedisce l'iniezione di codice:

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

(utilizzando HTML5 stile Thymeleaf.)

Problemi correlati