Подтвердить что ты не робот

H: outputText не разбивает символы \r\n на новые строки

У меня есть переменная String, которая содержит возврат каретки и новые строки \r\n.

text = "Text1\r\nText2\r\nText3";

Я представляю это, используя <h:outputtext>.

<h:outputText value="#{bean.text}" />

Но он не распознает символы новой строки и показывает, как показано ниже в веб-браузере.

Text1 Text2 Text3

Почему <h:outputText> не разбивает \n на новые строки?

Что я должен делать? Должен ли я заменить \n на <br />?

4b9b3361

Ответ 1

Разрывы строк в HTML представлены элементом <br />, а не символом \n. Более того, откройте средний исходный код HTML, щелкнув правой кнопкой мыши, просмотрите источник в браузере, и вы "увидите" \n повсюду. Однако они не представлены как таковые в окончательной HTML-презентации. Только <br /> будет.

Так что да, вам нужно заменить их на <br />.

<h:outputText value="#{fn:replace(bean.text,'\n','&lt;br/&gt;')}" escape="false" />

Примечание: при использовании Apache EL вместо Oracle EL дважды используйте обратную косую черту, как в \\n.

<h:outputText value="#{fn:replace(bean.text,'\\n','&lt;br/&gt;')}" escape="false" />

В противном случае вы столкнетесь с исключением с сообщением Failed to parse the expression with root cause org.apache.el.parser.ParseException: Encountered <ILLEGAL_CHARACTER>.

Это все, однако, уродливо, и escape="false" делает его чувствительным к XSS-атакам, если значение поступает от ввода для конечного пользователя, и вы не санируете его заранее. Лучшая альтернатива - продолжать использовать \n и установить свойство CSS white-space в предварительно отформатированный для родительского элемента. Если вы хотите обернуть строки в контексте элемента блока, установите pre-wrap. Или, если вы хотите также свернуть пробелы и табуляции, установите pre-line.

Э.Г.

<h:outputText value="#{bean.text}" styleClass="preformatted" />
.preformatted {
    white-space: pre-wrap;
}

Ответ 2

Это обычное поведение, в HTML-последовательных пробелах, таких как пробелы и строки, нормализуется, поэтому отображается как одно пространство. Вы получите тот же дисплей, если бы вы включили текст с помощью строк в прямом источнике HTML. Чтобы почернить строки в выводе, вам придется обернуть текст тегами pre или применить класс таблицы стилей:

<pre><h:outputText value="..."/></pre>

<div style="white-space: pre-wrap"><h:outputText value="..."/></div>

Для других возможных значений атрибута white-space смотрите эту страницу: http://www.w3schools.com/cssref/pr_text_white-space.asp

Ответ 3

Предыдущие ответы вызывали у меня проблемы с большими объемами текста, такими как чрезвычайно широкий вывод (без переноса текста), который style="white-space: pre-wrap" не исправил; или он просто отображал &lt;br/&gt; как текст, а не как конец строки.

В конце концов, я использовал компонент h:inputTextarea для отображения текста и сделал его "только для чтения", который работал сразу, без замены разрывов строк, без необходимости использования дополнительных стилей или styleClasses. И его можно изменять в соответствии с потребностями пользователя, что является бонусом.

<h:inputTextarea cols="70" rows="10" readonly="true" value="#{bean.text}" /> 

Для небольших объемов текста я обнаружил, что опция pre-wrap, как подсказал Хенко выше, работает хорошо.