在Java中转义HTML的推荐方法
在普通Java代码中输出HTML时,有没有推荐的方法来逃避<
, >
, "
和&
字符?(除了手动执行以下操作)。
String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML"; String escaped = source.replace("<", "<").replace("&", "&"); // ...
来自Apache Commons Lang的 StringEscapeUtils :
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);
Apache Commons的替代方法:使用Spring的HtmlUtils.htmlEscape(String input)
方法。
有一个较新版本的Apache Commons Lang库 ,它使用不同的包名(org.apache.commons.lang3)。 现在, StringEscapeUtils
具有不同types的文档的不同types的静态方法( http://commons.apache.org/proper/commons-lang/javadocs/api-3.0/index.html )。 所以要转义HTML版本4.0string:
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");
好的简短方法:
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(); }
基于https://stackoverflow.com/a/8838023/1199155 (放大器是在那里失踪)。 根据http://www.w3.org/TR/html4/sgml/entities.html ,在if子句中检查的四个字符是128以下的唯一字符
在Android(API 16或更高版本)上,您可以:
Html.escapeHtml(textToScape);
或者更低的API:
TextUtils.htmlEncode(textToScape);
小心这个。 HTML文档中有许多不同的“上下文”:元素内部,引用的属性值,未引用的属性值,URL属性,JavaScript,CSS等等…您需要使用不同的编码方法这些防止跨站点脚本(XSS)。 查看OWASP XSS预防备忘单,了解每种情况的详细信息 – https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting):预防性的Cheat_Sheet。 您可以在OWASP ESAPI库中find每种上下文的转义方法 – https://github.com/ESAPI/esapi-java-legacy 。
对于那些使用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);
出于某些目的, HtmlUtils :
import org.springframework.web.util.HtmlUtils; [...] HtmlUtils.htmlEscapeDecimal("&")` //gives & HtmlUtils.htmlEscape("&")` //gives &
虽然org.apache.commons.lang.StringEscapeUtils.escapeHtml
@dfa答案很好,我过去也使用它,但不应该用于转义HTML(或XML) 属性,否则空格将被标准化(意味着所有相邻的空格字符成为一个单一的空间)。
我知道这一点,因为我已经对我的库(JATL)提交了缺less空白的属性的错误。 因此,我有一个(复制粘贴) 类(我从JDOM中偷了一些)来区分属性和元素内容的转义 。
虽然这可能不像过去那么重要(适当的属性转义),但由于使用了HTML5的data-
属性用法,它越来越受到人们的关注。