在Java中转义HTML的推荐方法

在普通Java代码中输出HTML时,有没有推荐的方法来逃避<>"&字符?(除了手动执行以下操作)。

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

来自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 &#38; HtmlUtils.htmlEscape("&")` //gives &amp; 

虽然org.apache.commons.lang.StringEscapeUtils.escapeHtml @dfa答案很好,我过去也使用它,但不应该用于转义HTML(或XML) 属性,否则空格将被标准化(意味着所有相邻的空格字符成为一个单一的空间)。

我知道这一点,因为我已经对我的库(JATL)提交了缺less空白的属性的错误。 因此,我有一个(复制粘贴) 类(我从JDOM中偷了一些)来区分属性和元素内容的转义 。

虽然这可能不像过去那么重要(适当的属性转义),但由于使用了HTML5的data-属性用法,它越来越受到人们的关注。