`
xhfei
  • 浏览: 115886 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多
转自(http://xhfei.iteye.com/admin/blogs/new
Spring 不但提供了一个功能全面的应用开发框架,本身还拥有众多可以在程序编写时直接
使用的工具类,您不但可以在 Spring 应用中使用这些工具类,也可以在其它的应用中使用,这些工具类中的大部分是可以在脱离 Spring 框架时使用的。了解 Spring 中有哪些好用的工具类并在程序编写时适当使用,将有助于提高开发效率、增强代码质量。   
   
 在这个分为两部分的文章中,我们将从众多的 Spring 工具类中遴选出那些好用的工具类介绍给大家。第 1 部分 介绍了与文件资源操作和 Web 相关的工具类。在第 2 部分中将介绍特殊字符转义和方法入参检测工具类。   
   
 特殊字符转义   
   
 由于 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 提供了三个转义方法:   
   
 方法 说明    
 static String htmlEscape(String input)  将 HTML 特殊字符转义为 HTML 通用转义序列;    
 static String htmlEscapeDecimal(String input)  将 HTML 特殊字符转义为带 # 的十进制数据转义序列;    
 static String htmlEscapeHex(String input)  将 HTML 特殊字符转义为带 # 的十六进制数据转义序列;    
   
 此外,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>   
     
   
   
 您只要使用 HtmlUtils 对代码 清单 1 的 userName 和 address 进行转义处理,最终输出的 HTML 页面就不会遭受破坏了。   
   
 JavaScript 特殊字符转义   
   
 JavaScript 中也有一些需要特殊处理的字符,如果直接将它们嵌入 JavaScript 代码中,JavaScript 程序结构将会遭受破坏,甚至被嵌入一些恶意的程序。下面列出了需要转义的特殊 JavaScript 字符:   
   
 ' :\'    
 " :\"    
 \ :\\    
 走纸换页: \f    
 换行:\n    
 换栏符:\t    
 回车:\r    
 回退符:\b    
     
 我们通过一个具体例子演示动态变量是如何对 JavaScript 程序进行破坏的。假设我们有一个 JavaScript 数组变量,其元素值通过一个 Java List 对象提供,下面是完成这一操作的 JSP 代码片断:   
   
   
 清单 3. jsTest.jsp:未对 JavaScript 特殊字符进行处理   
                    
 <%@ page language="java" contentType="text/html; charset=utf-8"%>   
 <jsp:directive.page import="java.util.*"/>   
 <%   
   List textList = new ArrayList();   
   textList.add("\";alert();j=\"");   
 %>   
 <script>   
   var txtList = new Array();   
    <% for ( int i = 0 ; i < textList.size() ; i++) { %>   
      txtList[<%=i%>] = "<%=textList.get(i)%>";    
      ① 未对可能包含特殊 JavaScript 字符的变量进行处理   
    <% } %>   
 </script>   
     
   
   
 当客户端调用这个 JSP 页面后,将得到以下的 HTML 输出页面:   
   
 <script>   
   var txtList = new Array();   
    txtList[0] = "";alert();j=""; ① 本来是希望接受一个字符串,结果被植入了一段JavaScript代码   
 </script>   
     
   
   
 由于包含 JavaScript 特殊字符的 Java 变量直接合并到 JavaScript 代码中,我们本来期望 ① 处所示部分是一个普通的字符串,但结果变成了一段 JavaScript 代码,网页将弹出一个 alert 窗口。想像一下如果粗体部分的字符串是“";while(true)alert();j="”时会产生什么后果呢?   
   
 因此,如果网页中的 JavaScript 代码需要通过拼接 Java 变量动态产生时,一般需要对变量的内容进行转义处理,可以通过 Spring 的 JavaScriptUtils 完成这件工作。下面,我们使用 JavaScriptUtils 对以上代码进行改造:   
   
 <%@ page language="java" contentType="text/html; charset=utf-8"%>   
 <jsp:directive.page import="java.util.*"/>   
 <jsp:directive.page import="org.springframework.web.util.JavaScriptUtils"/>   
 <%   
   List textList = new ArrayList();   
   textList.add("\";alert();j=\"");   
 %>   
 <script>   
    var txtList = new Array();   
    <% for ( int i = 0 ; i < textList.size() ; i++) { %>   
    ① 在输出动态内容前事先进行转义处理   
    txtList[<%=i%>] = "<%=JavaScriptUtils.javaScriptEscape(""+textList.get(i))%>";   
    <% } %>   
 </script>   
     
   
   
 通过转义处理后,这个 JSP 页面输出的结果网页的 JavaScript 代码就不会产生问题了:   
   
 <script>   
    var txtList = new Array();   
    txtList[0] = "\";alert();j=\"";   
    ① 粗体部分仅是一个普通的字符串,而非一段 JavaScript 的语句了   
 </script>   
     
   
   
 SQL特殊字符转义   
   
 应该说,您即使没有处理 HTML 或 JavaScript 的特殊字符,也不会带来灾难性的后果,但是如果不在动态构造 SQL 语句时对变量中特殊字符进行处理,将可能导致程序漏洞、数据盗取、数据破坏等严重的安全问题。网络中有大量讲解 SQL 注入的文章,感兴趣的读者可以搜索相关的资料深入研究。   
   
 虽然 SQL 注入的后果很严重,但是只要对动态构造的 SQL 语句的变量进行特殊字符转义处理,就可以避免这一问题的发生了。来看一个存在安全漏洞的经典例子:   
   
 SELECT COUNT(userId)    
 FROM t_user    
 WHERE userName='"+userName+"' AND password ='"+password+"';   
     
   
   
 以上 SQL 语句根据返回的结果数判断用户提供的登录信息是否正确,如果 userName 变量不经过特殊字符转义处理就直接合并到 SQL 语句中,黑客就可以通过将 userName 设置为 “1' or '1'='1”绕过用户名/密码的检查直接进入系统了。   
   
 所以除非必要,一般建议通过 PreparedStatement 参数绑定的方式构造动态 SQL 语句,因为这种方式可以避免 SQL 注入的潜在安全问题。但是往往很难在应用中完全避免通过拼接字符串构造动态 SQL 语句的方式。为了防止他人使用特殊 SQL 字符破坏 SQL 的语句结构或植入恶意操作,必须在变量拼接到 SQL 语句之前对其中的特殊字符进行转义处理。Spring 并没有提供相应的工具类,您可以通过 jakarta commons lang 通用类包中(spring/lib/jakarta-commons/commons- lang.jar)的 StringEscapeUtils 完成这一工作:   
   
   
 清单 4. SqlEscapeExample   
                    
 package com.baobaotao.escape;   
 import org.apache.commons.lang.StringEscapeUtils;   
 public class SqlEscapeExample {   
     public static void main(String[] args) {   
         String userName = "1' or '1'='1";   
         String password = "123456";   
         userName = StringEscapeUtils.escapeSql(userName);   
         password = StringEscapeUtils.escapeSql(password);   
         String sql = "SELECT COUNT(userId) FROM t_user WHERE userName='"  
             + userName + "' AND password ='" + password + "'";   
         System.out.println(sql);   
     }   
 }   
     
   
   
 事实上,StringEscapeUtils 不但提供了 SQL 特殊字符转义处理的功能,还提供了 HTML、XML、 JavaScript、Java 特殊字符的转义和还原的方法。如果您不介意引入 jakarta commons lang 类包,我们更推荐您使用 StringEscapeUtils 工具类完成特殊字符转义处理的工作。     
分享到:
评论
2 楼 wl296784423 2012-09-20  
撒的发
1 楼 wl296784423 2012-09-20  
阿萨德发生的[b][/b][i][/i][u][/u]

相关推荐

    插入数据库之前将特殊字符转义

    这篇博客“插入数据库之前将特殊字符转义”深入探讨了这个关键话题。 SQL注入是一种常见的网络攻击方式,攻击者通过输入包含恶意SQL代码的字符串,欺骗数据库执行非预期的操作。例如,如果用户输入未经过滤的“' OR...

    正则表达式特殊字符的转义

    正则表达式特殊字符的转义,常用网页特殊字符转义,网络爬虫特殊字符处理

    java csv 读写框架特殊字符转义.docx

    "java csv 读写框架特殊字符转义" Java CSV 读写框架是基于 Java 注解的 CSV 读写框架,具有 Fluent 流式写法、基于 Java 注解、支持自定义的转换和机敏配置、内置 8 大根本类型以及 String 类型转换等特性。该框架...

    HTML特殊字符转义对照字典表

    完整的HTML特殊字符转义对照表,一表在手,放心使用,从此告别百度

    基于sqlite特殊字符转义的实现方法

    总之,SQLite特殊字符转义是保证SQL查询正确执行的关键步骤,开发者应确保在处理用户输入时采取适当措施。同时,熟悉SQLite的基本操作和最佳实践,对于提升数据库管理的效率和安全性有着重要意义。

    【JavaScript源代码】基于网址URL中特殊字符转义编码.docx

    【JavaScript源代码】基于网址URL中特殊字符转义编码是一个重要的概念,特别是在Web开发中,因为URL是连接互联网资源的基本途径。URL编码是确保数据在URL中正确传递的关键步骤,尤其是当URL包含特殊字符或者非ASCII...

    js特殊字符转义介绍

    在JavaScript编程中,特殊字符转义是处理字符串中的特定字符的一种方法。特殊字符往往具有特殊的含义或作用,在特定的上下文中可能会改变代码的运行方式。为了避免这些问题,JavaScript提供了一套转义序列,可以使用...

    HTML特殊转义字符列表

    web开发时 html 页面 特殊字符转义大全 如 引号 冒号 空格等等

    两种方法解决javascript url post 特殊字符转义 + & #

    本文主要介绍在JavaScript中遇到的URL传递数据时,如何处理特殊字符的转义问题。 在进行URL传值的时候,数据丢失实际上并非真正的丢失,而是由于特殊字符在URL中有特殊的意义,被浏览器解释为URL的一部分。例如,...

    Java正则表达式处理特殊字符转义的方法

    正则表达式中的特殊字符转义通常通过在字符前添加反斜杠`\`来实现。例如,如果要匹配一个实际的星号`*`,我们需要写成`\*`。同样的,其他特殊字符如圆括号`()`、点`.`、方括号`[]`、问号`?`、反斜杠`\`、花括号`{}`...

    escapestringregexp特殊字符转义正则表达式

    `escape-string-regexp` 是一个非常实用的工具库,专门用于转义正则表达式中的特殊字符。这个库由Sindre Sorhus创建,其GitHub仓库的最新提交版本为14b8379。 正则表达式中包含一些具有特殊含义的字符,例如 `\`, `...

    Mybatis自定义拦截器,对模糊查询传值的特殊字符统一进行转义处理的代码

    特殊字符(\,_,%)转义工具类 MyQueryInterceptor.java: Mybatis自定义拦截器 注意:该拦截器只支持QueryWrapper的like方法,serviceImpl层传全角模糊查询(%%) mapper或xml层的全角模糊查询(%*%)和半角模糊查询(%*或*%)

    Shell命令行中特殊字符与其转义详解(去除特殊含义)

    转义字符`\`是最常用的特殊字符转义方法,将其放在特殊字符前即可使其失效。例如,如果想打印名为`test*`的文件内容,可以使用`cat test\*`,这里的`\`告诉Shell不要将`*`作为通配符处理。 单引号`' '`和双引号`" ...

    转义表单提交字符处理函数

    - **功能**:此函数用于准备字符串以安全地插入到MySQL数据库中,通过转义特殊字符来防止SQL注入。 - **语法**:`mysql_real_escape_string(string, connection)` - **参数**: - `string`:要转义的字符串。 -...

    国际民航组织特殊字符转换规则.pdf

    国际民航组织特殊字符转换规则.pdf

    xml 的特殊字符的处理方法

    ### XML特殊字符转义 1. `转义为 `&lt;` 2. `&gt;` 转义为 `&gt;` 3. `&` 转义为 `&amp;` 4. `'` 转义为 `&apos;` 5. `"` 转义为 `&quot;` 例如,如果你的XML数据中包含字符串 `"It's a &lt;good&gt; day!"`,你应该将其...

    彻底根治Spring @ResponseBody JavaScript HTML特殊字符

    为防止这种情况,我们需要对特殊字符进行转义,例如将`转义为`&lt;`,`&gt;`转义为`&gt;`,`"`转义为`&quot;`,`'`转义为`&apos;`,`&`转义为`&amp;`,`\`转义为`\`。 2. **Spring MVC的解决方案**: - Spring MVC...

Global site tag (gtag.js) - Google Analytics