2015-05-22 116 views
16

Tôi đang sử dụng công cụ mẫu Thymeleaf với mùa xuân và tôi muốn hiển thị văn bản được lưu trữ qua một vùng văn bản nhiều dòng.Thymeleaf + Spring: Làm cách nào để ngắt dòng?

Trong chuỗi cơ sở dữ liệu nhiều dòng của tôi là cửa hàng với "\ n" như thế này: "Test1 \ nTest2 \ n ...."

Với thứ: văn bản tôi đã có: "Test1 Test2" không có dòng phá vỡ.

Làm cách nào tôi có thể hiển thị ngắt dòng bằng Thymeleaf và tránh thay thế "\ n" theo cách thủ công bằng < br /> và sau đó tránh sử dụng th: utext (dạng mở này để phun xss)?

Cảm ơn!

Trả lời

18

Bạn có hai lựa chọn:

  1. Sử dụng thứ: utext - tùy chọn cài đặt dễ dàng, nhưng khó khăn hơn để đọc và ghi nhớ
  2. Tạo một bộ xử lý tùy chỉnh và phương ngữ - nhiều thiết lập liên quan, nhưng dễ sử dụng hơn, dễ đọc hơn trong tương lai.

Lựa chọn 1:

Bạn có thể sử dụng thứ: utext nếu bạn thoát khỏi văn bản bằng cách sử dụng phương pháp hữu ích biểu #strings.escapeXml(text) để ngăn ngừa XSS tiêm và định dạng không mong muốn - http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#strings

Để làm cho nền tảng này độc lập , bạn có thể sử dụng T(java.lang.System).getProperty('line.separator') để lấy dấu tách dòng.

Sử dụng các tiện ích biểu Thymeleaf hiện có, công trình này:

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

Phương án 2:

Sau khi cài đặt hoàn tất, tất cả các bạn sẽ cần phải làm gì để đạt được sản lượng textline thoát với ngắt dòng bảo quản :

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

Phần chính làm công việc là bộ xử lý. Đoạn mã sau sẽ thực hiện thủ thuật:

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


} 

Bây giờ bạn có bộ xử lý, bạn cần có phương ngữ tùy chỉnh để thêm bộ xử lý vào.

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

} 

Bây giờ bạn cần phải thêm nó vào xml hoặc java của bạn cấu hình:

Nếu bạn đang viết một ứng dụng Spring MVC, bạn chỉ cần cài đặt nó tại additionalDialects tài sản của đậu Template Engine, nên rằng nó được bổ sung vào phương ngữ SpringStandard mặc định:

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

Hoặc nếu bạn đang sử dụng Spring và thà sử dụng JavaConfig bạn có thể tạo ra một lớp chú thích với @Configuration trong gói cơ sở của bạn có chứa các phương ngữ như một bean được quản lý:

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

Dưới đây là một số tài liệu tham khảo thêm về việc tạo ra bộ vi xử lý tùy chỉnh và tiếng địa phương: http://www.thymeleaf.org/doc/articles/sayhelloextendingthymeleaf5minutes.html, http://www.thymeleaf.org/doc/articles/sayhelloagainextendingthymeleafevenmore5minutes.htmlhttp://www.thymeleaf.org/doc/tutorials/2.1/extendingthymeleaf.html

+0

Giải pháp hoàn hảo cho tôi! Cảm ơn sự giúp đỡ của bạn – Chettor

+1

@Chettor Tôi không chắc liệu Stackoverflow có cập nhật cho bạn khi câu trả lời được sửa đổi hay không, nhưng tôi đã bao gồm việc triển khai ví dụ cho phương pháp xử lý và phương ngữ tùy chỉnh. Hy vọng nó giúp! –

+0

Nó sẽ giúp tôi, Cảm ơn! –

0

Hãy thử điều này

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

Đó là gần hoàn hảo! Cảm ơn Đường line được hiển thị chính xác NHƯNG khi loại người dùng thoát ký tự như "hoặc" hiển thị \ "hoặc \ '(với dấu gạch chéo ngược). Có cách nào để ngăn chặn không? – Chettor

3

Trong trường hợp của tôi escapeJava() trả về giá trị unicode cho các ký hiệu Cyrillic, vì vậy tôi quấn tất cả trong unescapeJava() phương pháp giúp đỡ để giải quyết của tôi vấn đề.

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

Có lẽ không phải những gì OP đã có trong tâm trí, nhưng hoạt động này và ngăn chặn mã tiêm:

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

(Sử dụng HTML5 kiểu Thymeleaf.)

Các vấn đề liên quan