`

org.springframework.web.util.HtmlUtils,特殊字符转义

 
阅读更多
特殊字符转义

由于 Web 应用程序需要联合使用到多种语言,每种语言都包含一些特殊的字符,对于动态语言或标签式的语言而言,如果需要动态构造语言的内容时,一个我们经常会碰到的问题就是特殊字符转义的问题。下面是 Web 开发者最常面对需要转义的特殊字符类型:

•HTML 特殊字符;
•JavaScript 特殊字符;
•SQL 特殊字符;
如果不对这些特殊字符进行转义处理,则不但可能破坏文档结构,还可以引发潜在的安全问题。Spring 为 HTML 和 JavaScript 特殊字符提供了转义操作工具类,它们分别是 HtmlUtils 和 JavaScriptUtils。

HTML 特殊字符转义

HTML 中 <,>,& 等字符有特殊含义,它们是 HTML 语言的保留字,因此不能直接使用。使用这些个字符时,应使用它们的转义序列:

•&:&amp;
•" :&quot;
•< :&lt;
•> :&gt;
由于 HTML 网页本身就是一个文本型结构化文档,如果直接将这些包含了 HTML 特殊字符的内容输出到网页中,极有可能破坏整个 HTML 文档的结构。所以,一般情况下需要对动态数据进行转义处理,使用转义序列表示 HTML 特殊字符。下面的 JSP 网页将一些变量动态输出到 HTML 网页中:


清单 1. 未进行 HTML 特殊字符转义处理网页

<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%!
   String userName = "</td><tr></table>";
   String address = " \" type=\"button";
 %>
<table border="1">
   <tr>
     <td>姓名:</td><td><%=userName%></td> ①
   </tr>
   <tr>
     <td>年龄:</td><td>28</td>
   </tr>
</table>
 <input value="<%=address%>"  type="text" /> ②


在 ① 和 ② 处,我们未经任何转义处理就直接将变量输出到 HTML 网页中,由于这些变量可能包含一些特殊的 HTML 的字符,它们将可能破坏整个 HTML 文档的结构。我们可以从以上 JSP 页面的一个具体输出中了解这一问题:

<table border="1">
   <tr>
     <td>姓名:</td><td></td><tr></table></td> 
     ① 破坏了 <table> 的结构
   </tr>
   <tr>
     <td>年龄:</td><td>28</td>
   </tr>
</table>
 <input value=" " type="button"  type="text" /> 
 ② 将本来是输入框组件偷梁换柱为按钮组件
 

融合动态数据后的 HTML 网页已经面目全非,首先 ① 处的 <table> 结构被包含 HTML 特殊字符的 userName 变量截断了,造成其后的 <table> 代码变成无效的内容;其次,② 处 <input> 被动态数据改换为按钮类型的组件(type="button")。为了避免这一问题,我们需要事先对可能破坏 HTML 文档结构的动态数据进行转义处理。Spring 为我们提供了一个简单适用的 HTML 特殊字符转义工具类,它就是 HtmlUtils。下面,我们通过一个简单的例子了解 HtmlUtils 的具体用法:


清单 2. HtmpEscapeExample

package com.baobaotao.escape;
import org.springframework.web.util.HtmlUtils;
public class HtmpEscapeExample {
    public static void main(String[] args) {
        String specialStr = "<div id=\"testDiv\">test1;test2</div>";
        String str1 = HtmlUtils.htmlEscape(specialStr); ①转换为HTML转义字符表示
        System.out.println(str1);
       
        String str2 = HtmlUtils.htmlEscapeDecimal(specialStr); ②转换为数据转义表示
        System.out.println(str2);
       
        String str3 = HtmlUtils.htmlEscapeHex(specialStr); ③转换为十六进制数据转义表示
        System.out.println(str3);
       
        ④下面对转义后字符串进行反向操作
        System.out.println(HtmlUtils.htmlUnescape(str1));
        System.out.println(HtmlUtils.htmlUnescape(str2));
        System.out.println(HtmlUtils.htmlUnescape(str3));
    }
}
 


HTML 不但可以使用通用的转义序列表示 HTML 特殊字符,还可以使用以 # 为前缀的数字序列表示 HTML 特殊字符,它们在最终的显示效果上是一样的。HtmlUtils 提供了三个转义方法:

此外,HtmlUtils 还提供了一个能够将经过转义内容还原的方法:htmlUnescape(String input),它可以还原以上三种转义序列的内容。运行以上代码,您将可以看到以下的输出:

str1:&lt;div id=&quot;testDiv&quot;&gt;test1;test2&lt;/div&gt;
str2:&#60;div id=&#34;testDiv&#34;&#62;test1;test2&#60;/div&#62;
str3:&#x3c;div id=&#x22;testDiv&#x22;&#x3e;test1;test2&#x3c;/div&#x3e;
<div id="testDiv">test1;test2</div>
<div id="testDiv">test1;test2</div>
<div id="testDiv">test1;test2</div>
 




/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.util;

/**
 * Utility class for HTML escaping. Escapes and unescapes
 * based on the W3C HTML 4.01 recommendation, handling
 * character entity references.
 *
 * <p>Reference:
 * <a href="http://www.w3.org/TR/html4/charset.html">http://www.w3.org/TR/html4/charset.html</a>
 *
 * <p>For a comprehensive set of String escaping utilities,
 * consider Jakarta Commons Lang and its StringEscapeUtils class.
 * We are not using that class here to avoid a runtime dependency
 * on Commons Lang just for HTML escaping. Furthermore, Spring's
 * HTML escaping is more flexible and 100% HTML 4.0 compliant.
 *
 * @author Juergen Hoeller
 * @author Martin Kersten
 * @since 01.03.2003
 * @see org.apache.commons.lang.StringEscapeUtils
 */
public abstract class HtmlUtils {

	/**
	 * Shared instance of pre-parsed HTML character entity references.
	 */
	private static final HtmlCharacterEntityReferences characterEntityReferences =
			new HtmlCharacterEntityReferences();


	/**
          * 将 HTML 特殊字符转义为 HTML 通用转义序列;
	 * Turn special characters into HTML character references.
	 * Handles complete character set defined in HTML 4.01 recommendation.
	 * <p>Escapes all special characters to their corresponding
	 * entity reference (e.g. <code>&lt;</code>).
	 * <p>Reference:
	 * <a href="http://www.w3.org/TR/html4/sgml/entities.html">
	 * http://www.w3.org/TR/html4/sgml/entities.html
	 * </a>
	 * @param input the (unescaped) input string
	 * @return the escaped string
	 */
	public static String htmlEscape(String input) {
		if (input == null) {
			return null;
		}
		StringBuilder escaped = new StringBuilder(input.length() * 2);
		for (int i = 0; i < input.length(); i++) {
			char character = input.charAt(i);
			String reference = characterEntityReferences.convertToReference(character);
			if (reference != null) {
				escaped.append(reference);
			}
			else {
				escaped.append(character);
			}
		}
		return escaped.toString();
	}

	/**
          	 * 将 HTML 特殊字符转义为带 # 的十进制数据转义序列;
	 * Turn special characters into HTML character references.
	 * Handles complete character set defined in HTML 4.01 recommendation.
	 * <p>Escapes all special characters to their corresponding numeric
	 * reference in decimal format (&#<i>Decimal</i>;).
	 * <p>Reference:
	 * <a href="http://www.w3.org/TR/html4/sgml/entities.html">
	 * http://www.w3.org/TR/html4/sgml/entities.html
	 * </a>
	 * @param input the (unescaped) input string
	 * @return the escaped string
	 */
	public static String htmlEscapeDecimal(String input) {
		if (input == null) {
			return null;
		}
		StringBuilder escaped = new StringBuilder(input.length() * 2);
		for (int i = 0; i < input.length(); i++) {
			char character = input.charAt(i);
			if (characterEntityReferences.isMappedToReference(character)) {
				escaped.append(HtmlCharacterEntityReferences.DECIMAL_REFERENCE_START);
				escaped.append((int) character);
				escaped.append(HtmlCharacterEntityReferences.REFERENCE_END);
			}
			else {
				escaped.append(character);
			}
		}
		return escaped.toString();
	}

	/**
          	 * 将 HTML 特殊字符转义为带 # 的十六进制数据转义序列;
	 * Turn special characters into HTML character references.
	 * Handles complete character set defined in HTML 4.01 recommendation.
	 * <p>Escapes all special characters to their corresponding numeric
	 * reference in hex format (&#x<i>Hex</i>;).
	 * <p>Reference:
	 * <a href="http://www.w3.org/TR/html4/sgml/entities.html">
	 * http://www.w3.org/TR/html4/sgml/entities.html
	 * </a>
	 * @param input the (unescaped) input string
	 * @return the escaped string
	 */
	public static String htmlEscapeHex(String input) {
		if (input == null) {
			return null;
		}
		StringBuilder escaped = new StringBuilder(input.length() * 2);
		for (int i = 0; i < input.length(); i++) {
			char character = input.charAt(i);
			if (characterEntityReferences.isMappedToReference(character)) {
				escaped.append(HtmlCharacterEntityReferences.HEX_REFERENCE_START);
				escaped.append(Integer.toString((int) character, 16));
				escaped.append(HtmlCharacterEntityReferences.REFERENCE_END);
			}
			else {
				escaped.append(character);
			}
		}
		return escaped.toString();
	}

	/**
	 	 * Turn HTML character references into their plain text UNICODE equivalent.
	 * <p>Handles complete character set defined in HTML 4.01 recommendation
	 * and all reference types (decimal, hex, and entity).
	 * <p>Correctly converts the following formats:
	 * <blockquote>
	 * &amp;#<i>Entity</i>; - <i>(Example: &amp;amp;) case sensitive</i>
	 * &amp;#<i>Decimal</i>; - <i>(Example: &amp;#68;)</i><br>
	 * &amp;#x<i>Hex</i>; - <i>(Example: &amp;#xE5;) case insensitive</i><br>
	 * </blockquote>
	 * Gracefully handles malformed character references by copying original
	 * characters as is when encountered.<p>
	 * <p>Reference:
	 * <a href="http://www.w3.org/TR/html4/sgml/entities.html">
	 * http://www.w3.org/TR/html4/sgml/entities.html
	 * </a>
	 * @param input the (escaped) input string
	 * @return the unescaped string
	 */
	public static String htmlUnescape(String input) {
		if (input == null) {
			return null;
		}
		return new HtmlCharacterEntityDecoder(characterEntityReferences, input).decode();
	}

}




参考资料

学习

http://www.ibm.com/developerworks/cn/java/j-lo-spring-utils2/
分享到:
评论

相关推荐

    spring-web-2.5.jar

    org.springframework.web.util.HtmlUtils.class org.springframework.web.util.HttpSessionMutexListener.class org.springframework.web.util.IntrospectorCleanupListener.class org.springframework.web.util....

    org.springframework.web的jar包.zip

    在本篇文章中,我们将深入探讨`org.springframework.web`包中的关键概念,特别是`ServerEndpointExporter`类在WebSocket服务器端点中的作用。 首先,让我们了解`org.springframework.web`包的基本构成。这个包主要...

    org.springframework.core.jar

    `org.springframework.util`则包含了一系列通用的工具类,如对象处理、集合操作、字符串处理等,极大地提升了开发效率。 2. **资源管理**:`org.springframework.core.io`包定义了资源接口,统一了文件、URL、输入/...

    Spring框架依赖jar包

    Spring框架依赖jar包,其中最小依赖包:org.springframework.core、org.springframework.context、org.springframework.beans、org.springframework.asm、org.springframework.expression、...

    org.springframework.expression-3.1.1.RELEASE.jar

    在`org.springframework.expression-3.1.1.RELEASE.jar`这个库中,包含了所有实现SpEL功能的类和接口,如`ExpressionParser`用于解析表达式,`EvaluationContext`用于提供上下文信息,以及`ValueExpression`表示一个...

    spring_MVC源码

    09. &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt; 10. &lt;/listener&gt; 11. 12. &lt;servlet&gt; 13. &lt;servlet-name&gt;spring&lt;/servlet-name&gt; 14. &lt;servlet-class&gt;org.spring...

    springboot 基础简易实例, maven项目

    import org.springframework.web.bind.annotation.RestController; // @RestController返回的是json @RestController public class HelloWorldController { // http://localhost:8080/hello 返回的是文本"Hello ...

    Spring项目中怎么配置log4j

    &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener ``` 以上就是Spring项目中配置log4j的基本步骤和关键知识点。通过合理配置,我们可以实现日志的高效管理和监控,从而提升开发和运维的效率。

    spring-framework.jar包

    这个"spring-framework.jar"包包含了Spring框架的所有组件和依赖,使得开发者在学习和使用Spring时无需逐一下载各个模块。这里我们将深入探讨Spring框架的核心知识点。 首先,Spring的核心理念是依赖注入...

    spring4.0 API

    spring 4.0 未翻译java.lang....org.springframework.core.OrderComparator (implements java.util.Comparator) org.springframework.core.annotation.AnnotationAwareOrderComparator Annotation Type Hierarchy

    spring jdbctemplate 封裝

    import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSetMetaData; ...

    spring-framework-3.0.5.RELEASE-dependencies-1

    spring-framework-3.0.5.RELEASE-dependencies 好不容易找到了,赶紧分享一下 因为不能大于20M,共分了8个包,都是...org.springframework.build org.testng org.xmlpull org.joda org.jruby org.junit org.objectweb.asm

    redis-lock-master.zip

    分布式锁与信号量 包含测试用例和实验的JAVA代码 ... ... ... import org.junit.Test;...import org.junit.runner.RunWith;...import org.springframework.beans....import java.util.concurrent.*; @RunWith(SpringRunner.cla

    java head space.txt

    org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space at org.springframework.web.servlet.DispatcherServlet....

    基于spring boot 日志(logback)报错的解决方式

    错误信息:"No converter found capable of converting from type [java.lang.String] to type [java.util.Map&lt;java.lang.String,java.lang.String&gt;] org.springframework.boot.context.properties.bind....

    spring2.5基于注解例子程序

    Spring 2.5是Spring框架的一个重要版本,它引入了大量增强的功能,特别是对注解的支持,这使得在Java应用程序中实现依赖注入和面向切面编程(AOP)变得更加简单和直观。在这个基于注解的例子程序中,我们将深入探讨...

    struts2驱动包

    nested exception is java.lang.AbstractMethodError: org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator.postProcessAfterInstantiation(Ljava/lang/Object;Ljava/lang/String;)Z at org....

    org.apache.poi jar包

    org.apache.poi JAR包,解决个人的 import org.apache.commons.beanutils.PropertyUtilsBean;...import org.apache.poi.ss.util.CellRangeAddress; "The import org.apache.poi cannot be resolved"的问题

    spring mvc 3.0.5 jar包

    - `org.springframework.web.struts-3.0.5.RELEASE.jar`:此包提供了与Apache Struts框架的集成,使得基于Struts的应用程序可以利用Spring MVC的功能。 - `org.springframework.web.servlet-3.0.5.RELEASE.jar`:...

    org.jasig.cas.client.util.CommonUtils

    予org.jasig.cas.client.util.CommonUtils 加入 public static void disableSSLVerification(){ try { // Create a trust manager that does not validate certificate chains TrustManager[] ...

Global site tag (gtag.js) - Google Analytics