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 />
?
Ответы
Ответ 1
Разрывы строк в HTML представлены элементом <br />
, а не символом \n
. Более того, откройте средний исходный код HTML, щелкнув правой кнопкой мыши, просмотрите источник в браузере, и вы "увидите" \n
повсюду. Однако они не представлены как таковые в окончательной HTML-презентации. Только <br />
будет.
Так что да, вам нужно заменить их на <br />
.
<h:outputText value="#{fn:replace(bean.text,'\n','<br/>')}" escape="false" />
Примечание: при использовании Apache EL вместо Oracle EL дважды используйте обратную косую черту, как в \\n
.
<h:outputText value="#{fn:replace(bean.text,'\\n','<br/>')}" 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"
не исправил; или он просто отображал <br/>
как текст, а не как конец строки.
В конце концов, я использовал компонент h:inputTextarea
для отображения текста и сделал его "только для чтения", который работал сразу, без замены разрывов строк, без необходимости использования дополнительных стилей или styleClasses. И его можно изменять в соответствии с потребностями пользователя, что является бонусом.
<h:inputTextarea cols="70" rows="10" readonly="true" value="#{bean.text}" />
Для небольших объемов текста я обнаружил, что опция pre-wrap
, как подсказал Хенко выше, работает хорошо.