Рекомендуемый метод экранирования HTML в Java

Есть ли рекомендуемый способ избежать символов <, >, " и & при выводе HTML в простой Java-код? (За исключением ручного выполнения следующего, то есть).

String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML";
String escaped = source.replace("<", "&lt;").replace("&", "&amp;"); // ...

Ответ 1

StringEscapeUtils из Apache Commons Lang:

import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
// ...
String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML";
String escaped = escapeHtml(source);

Для версия 3:

import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
// ...
String escaped = escapeHtml4(source);

Ответ 2

Альтернатива Apache Commons: используйте Spring HtmlUtils.htmlEscape(String input) метод.

Ответ 3

Хороший короткий метод:

public static String escapeHTML(String s) {
    StringBuilder out = new StringBuilder(Math.max(16, s.length()));
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
            out.append("&#");
            out.append((int) c);
            out.append(';');
        } else {
            out.append(c);
        }
    }
    return out.toString();
}

На основе fooobar.com/questions/32122/... (там отсутствует усилитель). Четыре символа, отмеченные в условии if, являются единственными ниже 128, согласно http://www.w3.org/TR/html4/sgml/entities.html

Ответ 4

Существует более новая версия Apache Commons Lang library и используется другое имя пакета (org.apache.commons.lang3). StringEscapeUtils теперь имеет разные статические методы для экранирования различных типов документов (http://commons.apache.org/proper/commons-lang/javadocs/api-3.0/index.html). Итак, чтобы избежать строки HTML версии 4.0:

import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;

String output = escapeHtml4("The less than sign (<) and ampersand (&) must be escaped before using them in HTML");

Ответ 5

Для тех, кто использует Google Guava:

import com.google.common.html.HtmlEscapers;
[...]
String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML";
String escaped = HtmlEscapers.htmlEscaper().escape(source);

Ответ 6

В андроиде (API 16 или выше) вы можете:

Html.escapeHtml(textToScape);

или для более низкого API:

TextUtils.htmlEncode(textToScape);

Ответ 7

Будьте осторожны с этим. Внутри HTML-документа имеется несколько разных "контекстов": внутри элемента, значение цитируемого атрибута, значение без кавычек, атрибут URL, javascript, CSS и т.д. Вам нужно будет использовать другой метод кодирования для каждого из чтобы предотвратить межсайтовый скриптинг (XSS). Для получения подробных сведений о каждом из этих контекстов проверьте OWASP XSS Предупреждающий чек-лист - https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet. Вы можете найти методы экранирования для каждого из этих контекстов в библиотеке OWASP ESAPI - https://github.com/ESAPI/esapi-java-legacy.

Ответ 8

Для некоторых целей HtmlUtils:

import org.springframework.web.util.HtmlUtils;
[...]
HtmlUtils.htmlEscapeDecimal("&"); //gives &#38;
HtmlUtils.htmlEscape("&"); //gives &amp;

Ответ 9

В то время как ответ @dfa org.apache.commons.lang.StringEscapeUtils.escapeHtml хорош, и я использовал его в прошлом, он не должен использоваться для экранирования HTML (или XML) атрибутов, иначе пробелы будут нормализованы (что означает все смежные пробельные символы становятся единым пространством).

Я знаю это, потому что у меня были ошибки, связанные с моей библиотекой (JATL) для атрибутов, где пробелы не сохранялись. Таким образом, у меня есть капля (copy n 'paste) класс (из которого я украл часть из JDOM), которая отличает экранирование атрибутов и содержимого элементов.

В то время как это могло быть не так важно в прошлом (надлежащее отключение атрибута), он все чаще становится более интересным с учетом использования использования атрибутов HTML5 data-.

Ответ 10

org.apache.commons.lang3.StringEscapeUtils больше не поддерживается. Теперь вы должны использовать org.apache.commons.text.StringEscapeUtils

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>${commons.text.version}</version>
    </dependency>