特殊字符转义
由于 Web 应用程序需要联合使用到多种语言,每种语言都包含一些特殊的字符,对于动态语言或标签式的语言而言,如果需要动态构造语言的内容时,一个我们经常会碰到的问题就是特殊字符转义的问题。下面是 Web 开发者最常面对需要转义的特殊字符类型:
•HTML 特殊字符;
•JavaScript 特殊字符;
•SQL 特殊字符;
如果不对这些特殊字符进行转义处理,则不但可能破坏文档结构,还可以引发潜在的安全问题。Spring 为 HTML 和 JavaScript 特殊字符提供了转义操作工具类,它们分别是 HtmlUtils 和 JavaScriptUtils。
HTML 特殊字符转义
HTML 中 <,>,& 等字符有特殊含义,它们是 HTML 语言的保留字,因此不能直接使用。使用这些个字符时,应使用它们的转义序列:
•&:&
•" :"
•< :<
•> :>
由于 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:<div id="testDiv">test1;test2</div>
str2:<div id="testDiv">test1;test2</div>
str3:<div id="testDiv">test1;test2</div>
<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><</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>
* &#<i>Entity</i>; - <i>(Example: &amp;) case sensitive</i>
* &#<i>Decimal</i>; - <i>(Example: &#68;)</i><br>
* &#x<i>Hex</i>; - <i>(Example: &#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/
分享到:
相关推荐
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`包中的关键概念,特别是`ServerEndpointExporter`类在WebSocket服务器端点中的作用。 首先,让我们了解`org.springframework.web`包的基本构成。这个包主要...
`org.springframework.util`则包含了一系列通用的工具类,如对象处理、集合操作、字符串处理等,极大地提升了开发效率。 2. **资源管理**:`org.springframework.core.io`包定义了资源接口,统一了文件、URL、输入/...
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`这个库中,包含了所有实现SpEL功能的类和接口,如`ExpressionParser`用于解析表达式,`EvaluationContext`用于提供上下文信息,以及`ValueExpression`表示一个...
09. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 10. </listener> 11. 12. <servlet> 13. <servlet-name>spring</servlet-name> 14. <servlet-class>org.spring...
import org.springframework.web.bind.annotation.RestController; // @RestController返回的是json @RestController public class HelloWorldController { // http://localhost:8080/hello 返回的是文本"Hello ...
<listener-class>org.springframework.web.util.Log4jConfigListener ``` 以上就是Spring项目中配置log4j的基本步骤和关键知识点。通过合理配置,我们可以实现日志的高效管理和监控,从而提升开发和运维的效率。
这个"spring-framework.jar"包包含了Spring框架的所有组件和依赖,使得开发者在学习和使用Spring时无需逐一下载各个模块。这里我们将深入探讨Spring框架的核心知识点。 首先,Spring的核心理念是依赖注入...
spring 4.0 未翻译java.lang....org.springframework.core.OrderComparator (implements java.util.Comparator) org.springframework.core.annotation.AnnotationAwareOrderComparator Annotation Type Hierarchy
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 好不容易找到了,赶紧分享一下 因为不能大于20M,共分了8个包,都是...org.springframework.build org.testng org.xmlpull org.joda org.jruby org.junit org.objectweb.asm
分布式锁与信号量 包含测试用例和实验的JAVA代码 ... ... ... import org.junit.Test;...import org.junit.runner.RunWith;...import org.springframework.beans....import java.util.concurrent.*; @RunWith(SpringRunner.cla
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space at org.springframework.web.servlet.DispatcherServlet....
错误信息:"No converter found capable of converting from type [java.lang.String] to type [java.util.Map<java.lang.String,java.lang.String>] org.springframework.boot.context.properties.bind....
Spring 2.5是Spring框架的一个重要版本,它引入了大量增强的功能,特别是对注解的支持,这使得在Java应用程序中实现依赖注入和面向切面编程(AOP)变得更加简单和直观。在这个基于注解的例子程序中,我们将深入探讨...
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包,解决个人的 import org.apache.commons.beanutils.PropertyUtilsBean;...import org.apache.poi.ss.util.CellRangeAddress; "The import org.apache.poi cannot be resolved"的问题
- `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 加入 public static void disableSSLVerification(){ try { // Create a trust manager that does not validate certificate chains TrustManager[] ...