我们主要通过两种形式提交向服务器发送请求:URL、表单。而表单形式一般都不会出现乱码问题,乱码问题主要是在URL上面。通过前面几篇博客的介绍我们知道URL向服务器发送请求编码过程实在是实在太混乱了。不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。如果程序员要把每一种结果都考虑进去,是不是太恐怖了?有没有办法,能够保证客户端只用一种编码方法向服务器发出请求?

有!这里我主要提供以下几种方法

一、javascript

使用javascript编码不给浏览器插手的机会,编码之后再向服务器发送请求,然后在服务器中解码。在掌握该方法的时候,我们需要料及javascript编码的三个方法:escape()、encodeURI()、encodeURIComponent()。

escape

采用SIO Latin字符集对指定的字符串进行编码。所有非ASCII字符都会被编码为%xx格式的字符串,其中xx表示该字符在字符集中所对应的16进制数字。例如,格式对应的编码为%20。它对应的解码方法为unescape()。

事实上escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。比如上面“我是cm”的结果为%u6211%u662Fcm,其中“我”对应的编码为6211,“是”的编码为662F,“cm”编码为cm。

注意,escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心。

encodeURI

对整个URL进行编码,它采用的是UTF-8格式输出编码后的字符串。不过encodeURI除了ASCII编码外对于一些特殊的字符也不会进行编码如:! @ # $& * ( ) = : / ; ? + '。

encodeURIComponent()

把URI字符串采用UTF-8编码格式转化成escape格式的字符串。相对于encodeURI,encodeURIComponent会更加强大,它会对那些在encodeURI()中不被编码的符号(; / ? : @ & = + $ , #)统统会被编码。但是encodeURIComponent只会对URL的组成部分进行个别编码,而不用于对整个URL进行编码。对应解码函数方法decodeURIComponent。

当然我们一般都是使用encodeURI方来进行编码操作。所谓的javascript两次编码后台两次解码就是使用该方法。javascript解决该问题有一次转码、两次转码两种解决方法。

一次转码

javascript转码:

var url = '<s:property value="webPath" />/ShowMoblieQRCode.servlet?name=我是cm';
window.location.href = encodeURI(url);

转码后的URL:http://127.0.0.1:8080/perbank/ShowMoblieQRCode.servlet?name=%E6%88%91%E6%98%AFcm

后台处理:

String name = request.getParameter("name");
System.out.println("前台传入参数:" + name);
name = new String(name.getBytes("ISO-8859-1"),"UTF-8");
System.out.println("经过解码后参数:" + name);

输出结果:

前台传入参数:??????cm

经过解码后参数:我是cm

二次转码

javascript

var url = '<s:property value="webPath" />/ShowMoblieQRCode.servlet?name=我是cm';
window.location.href = encodeURI(encodeURI(url));

转码后的url:http://127.0.0.1:8080/perbank/ShowMoblieQRCode.servlet?name=%25E6%2588%2591%25E6%2598%25AFcm

后台处理:

        String name = request.getParameter("name");
System.out.println("前台传入参数:" + name);
name = URLDecoder.decode(name,"UTF-8");
System.out.println("经过解码后参数:" + name);

输出结果:

前台传入参数:E68891E698AFcm

经过解码后参数:我是cm

filter

使用过滤器,过滤器LZ提供两种,第一种设置编码,第二种直接在过滤器中进行解码操作。

过滤器1

该过滤器是直接设置request的编码格式的。

public class CharacterEncoding implements Filter {
</span><span style="color: rgb(0,0,255)">private</span><span style="color: rgb(0,0,0)"> FilterConfig config ;
String encoding </span>= <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,0)">; </span><span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)"> destroy() {
config </span>= <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,0)">;
} </span><span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)"> doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) </span><span style="color: rgb(0,0,255)">throws</span><span style="color: rgb(0,0,0)"> IOException, ServletException {
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
} </span><span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span> init(FilterConfig config) <span style="color: rgb(0,0,255)">throws</span><span style="color: rgb(0,0,0)"> ServletException {
</span><span style="color: rgb(0,0,255)">this</span>.config =<span style="color: rgb(0,0,0)"> config;
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">获取配置参数</span>
String str = config.getInitParameter(&quot;encoding&quot;<span style="color: rgb(0,0,0)">);
</span><span style="color: rgb(0,0,255)">if</span>(str!=<span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,0)">){
encoding </span>=<span style="color: rgb(0,0,0)"> str;
}
}

}

配置:

<!-- 中文过滤器的配置 -->
<filter>
<filter-name>chineseEncoding</filter-name>
<filter-class>com.test.filter.CharacterEncoding</filter-class>
    <span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">init-param</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">param-name</span><span style="color: rgb(0,0,255)">&gt;</span>encoding<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">param-name</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">param-value</span><span style="color: rgb(0,0,255)">&gt;</span>utf-8<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">param-value</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">init-param</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">filter</span><span style="color: rgb(0,0,255)">&gt;</span> <span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">filter-mapping</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">filter-name</span><span style="color: rgb(0,0,255)">&gt;</span>chineseEncoding<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">filter-name</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">url-pattern</span><span style="color: rgb(0,0,255)">&gt;</span>/*<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">url-pattern</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">filter-mapping</span><span style="color: rgb(0,0,255)">&gt;</span></pre>

过滤器2

该过滤器在处理方法中将参数直接进行解码操作,然后将解码后的参数重新设置到request的attribute中。

public class CharacterEncoding implements Filter {
protected FilterConfig filterConfig ;
String encoding = null;
</span><span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)"> destroy() {
</span><span style="color: rgb(0,0,255)">this</span>.filterConfig = <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,0)">;
} </span><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)">
* 初始化
</span><span style="color: rgb(0,128,0)">*/</span>
<span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)"> init(FilterConfig filterConfig) {
</span><span style="color: rgb(0,0,255)">this</span>.filterConfig =<span style="color: rgb(0,0,0)"> filterConfig;
} </span><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)">
* 将 inStr 转为 UTF-8 的编码形式
*
* </span><span style="color: rgb(128,128,128)">@param</span><span style="color: rgb(0,128,0)"> inStr 输入字符串
* </span><span style="color: rgb(128,128,128)">@return</span><span style="color: rgb(0,128,0)"> UTF - 8 的编码形式的字符串
* </span><span style="color: rgb(128,128,128)">@throws</span><span style="color: rgb(0,128,0)"> UnsupportedEncodingException
</span><span style="color: rgb(0,128,0)">*/</span>
<span style="color: rgb(0,0,255)">private</span> String toUTF(String inStr) <span style="color: rgb(0,0,255)">throws</span><span style="color: rgb(0,0,0)"> UnsupportedEncodingException {
String outStr </span>= &quot;&quot;<span style="color: rgb(0,0,0)">;
</span><span style="color: rgb(0,0,255)">if</span> (inStr != <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,0)">) {
outStr </span>= <span style="color: rgb(0,0,255)">new</span> String(inStr.getBytes(&quot;iso-8859-1&quot;), &quot;UTF-8&quot;<span style="color: rgb(0,0,0)">);
}
</span><span style="color: rgb(0,0,255)">return</span><span style="color: rgb(0,0,0)"> outStr;
} </span><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)">
* 中文乱码过滤处理
</span><span style="color: rgb(0,128,0)">*/</span>
<span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)"> doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain chain) </span><span style="color: rgb(0,0,255)">throws</span><span style="color: rgb(0,0,0)"> IOException,
ServletException {
HttpServletRequest request </span>=<span style="color: rgb(0,0,0)"> (HttpServletRequest) servletRequest;
HttpServletResponse response </span>=<span style="color: rgb(0,0,0)"> (HttpServletResponse) servletResponse; </span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 获得请求的方式 (1.post or 2.get), 根据不同请求方式进行不同处理</span>
String method =<span style="color: rgb(0,0,0)"> request.getMethod();
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 1. 以 post 方式提交的请求 , 直接设置编码为 UTF-8</span>
<span style="color: rgb(0,0,255)">if</span> (method.equalsIgnoreCase(&quot;post&quot;<span style="color: rgb(0,0,0)">)) {
</span><span style="color: rgb(0,0,255)">try</span><span style="color: rgb(0,0,0)"> {
request.setCharacterEncoding(</span>&quot;UTF-8&quot;<span style="color: rgb(0,0,0)">);
} </span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)"> (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 2. 以 get 方式提交的请求</span>
<span style="color: rgb(0,0,255)">else</span><span style="color: rgb(0,0,0)"> {
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 取出客户提交的参数集</span>
Enumeration&lt;String&gt; paramNames =<span style="color: rgb(0,0,0)"> request.getParameterNames();
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 遍历参数集取出每个参数的名称及值</span>
<span style="color: rgb(0,0,255)">while</span><span style="color: rgb(0,0,0)"> (paramNames.hasMoreElements()) {
String name </span>= paramNames.nextElement(); <span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 取出参数名称</span>
String values[] = request.getParameterValues(name); <span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 根据参数名称取出其值
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 如果参数值集不为空</span>
<span style="color: rgb(0,0,255)">if</span> (values != <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,0)">) {
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 遍历参数值集</span>
<span style="color: rgb(0,0,255)">for</span> (<span style="color: rgb(0,0,255)">int</span> i = 0; i &lt; values.length; i++<span style="color: rgb(0,0,0)">) {
</span><span style="color: rgb(0,0,255)">try</span><span style="color: rgb(0,0,0)"> {
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 回圈依次将每个值调用 toUTF(values[i]) 方法转换参数值的字元编码</span>
String vlustr =<span style="color: rgb(0,0,0)"> toUTF(values[i]);
values[i] </span>=<span style="color: rgb(0,0,0)"> vlustr;
} </span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)"> (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 将该值以属性的形式藏在 request</span>

request.setAttribute(name, values);

}

}

    }
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 设置响应方式和支持中文的字元集</span>
response.setContentType(&quot;text/html;charset=UTF-8&quot;<span style="color: rgb(0,0,0)">); </span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)"> 继续执行下一个 filter, 无一下个 filter 则执行请求</span>

chain.doFilter(request, response);

}

}

配置:

<!-- 中文过滤器的配置 -->
<filter>
<filter-name>chineseEncoding</filter-name>
<filter-class>com.test.filter.CharacterEncoding</filter-class>
</filter>
<span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">filter-mapping</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">filter-name</span><span style="color: rgb(0,0,255)">&gt;</span>chineseEncoding<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">filter-name</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">url-pattern</span><span style="color: rgb(0,0,255)">&gt;</span>/*<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">url-pattern</span><span style="color: rgb(0,0,255)">&gt;</span>
<span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">filter-mapping</span><span style="color: rgb(0,0,255)">&gt;</span></pre>

其他

1、设置pageEncoding、contentType

<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>

2、设置tomcat的URIEncoding

在默认情况下,tomcat服务器使用的是ISO-8859-1编码格式来编码的,URIEncoding参数对get请求的URL进行编码,所以我们只需要在tomcat的server.xml文件的<Connector>标签中加上URIEncoding="utf-8"即可。


-----原文出自:http://cmsblogs.com/?p=1526,请尊重作者辛勤劳动成果,转载说明出处.

-----个人站点:http://cmsblogs.com

java中文乱码解决之道(八)-----解决URL中文乱码问题的更多相关文章

  1. java中文乱码解决之道(九)-----总结

    乱码,我们前台展示的杀手,可能有些朋友和我的经历一样:遇到乱码先按照自己的经验来解决,如果没有解决就google,运气好一搜就可以解决,运气不好可能够你折腾一番了.LZ之所以写这个系列博客就是因为遇到 ...

  2. java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**

    在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...

  3. java中文乱码解决之道(七)-----JSP页面编码过程

    我们知道JSP页面是需要转换为servlet的,在转换过程中肯定是要进行编码的.在JSP转换为servlet过程中下面一段代码起到至关重要的作用. <%@ page language=" ...

  4. java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**

    原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)—–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...

  5. java中文乱码解决之道(七)—–JSP页面编码过程

    我们知道JSP页面是需要转换为servlet的,在转换过程中肯定是要进行编码的.在JSP转换为servlet过程中下面一段代码起到至关重要的作用. <%@ page language=" ...

  6. java中文乱码解决之道(四)-----java编码转换过程

    前面三篇博客侧重介绍字符.编码问题,通过这三篇博客各位博友对各种字符编码有了一个初步的了解,要了解java的中文问题这是必须要了解的.但是了解这些仅仅只是一个开始,以下博客将侧重介绍java乱码是如何 ...

  7. java中文乱码解决之道(四)—–java编码转换过程

    原文出处:http://cmsblogs.com/?p=1475 前面三篇博客侧重介绍字符.编码问题,通过这三篇博客各位博友对各种字符编码有了一个初步的了解,要了解java的中文问题这是必须要了解的. ...

  8. Java乱码解决之道

    1.常见字符编码 ASCII编码: ASCII,American Standard Code for Information Interchange,是基于拉丁字母的一套电脑编码系统,主要用于显示现代 ...

  9. cocos2d-x 3.4 中文乱码解决之道

    cocos2dx 中文乱码解决之道 须要引入五个文件 1.iconv.h 2.iconvString.cpp 3.iconvString.h 4.iconv.dll 5.libiconv.lib 完整 ...

  10. ASP.NET开发在JavaScript有中文汉字时出现乱码时简单有效的解决

    一般情况在使用ASP.NET开发使用JavaScript有中文汉字时不会出现乱码情况,比如:alert('您看到我了吗?');这样直接输入中文汉字的代码中是不会出现乱码的,如果出现了,一是检查Web. ...

随机推荐

  1. HDU 1848 SG函数博弈

    Fibonacci again and again Problem Description   任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:F(1 ...

  2. ubuntu14 备份

    备份命令 # tar cvpjf backup.tar.bz2 –exclude=/proc –exclude=/lost+found –exclude=/backup.tar.bz2 –exclud ...

  3. sorl入门

    本教程是从别人的基础上借鉴整理的 Solr是一个独立的企业级搜索应用服务器,它对外提供API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引(solr生成倒排索引,数 ...

  4. LeetCode 412. Fizz Buzz

    Problem: Write a program that outputs the string representation of numbers from 1 to n. But for mult ...

  5. 可变参数列表与printf()函数的实现

    问题 当我们刚开始学习C语言的时候,就接触到printf()函数,可是当时"道行"不深或许不够细心留意,又或者我们理所当然地认为库函数规定这样就是这样,没有发现这个函数与普通的函数 ...

  6. 字典树+博弈 CF 455B A Lot of Games(接龙游戏)

    题目链接 题意: A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏.问A先手,经过k轮游戏,最后胜利的人是谁. 思路: 很 ...

  7. 2_MVC+EF+Autofac(dbfirst)轻型项目框架_用户权限验证

    前言 接上面两篇 0_MVC+EF+Autofac(dbfirst)轻型项目框架_基本框架 与 1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例) .在第一篇中介 ...

  8. 阅读jquery源码与js依赖加载的模块化!

    阅读源码肯定是先下载有注释的源码 我也是醉了,10309 行代码,在陆续续的一个月之内,看完了,虽有收获但收获不大, 直到又一次看jquery的github,怎么会有cmd????没听过使用jquer ...

  9. 【第二课】WEBIX 入门自学-获取WEBIX及相关资料

    下载WEBIX组件库 http://webix.com/download/ WEBIX在线文档 http://docs.webix.com/ 离线的手册 下载

  10. Windows安装mysql-5.7.17-winx64.zip方式

    1.去官网上下载.zip格式的文件. 2.解压到一个文件夹,这里我用D:\MySql表示 3.在D:\MySql\mysql-5.7.17-winx64下新建my.ini配置文件 黄色背景色的地方需要 ...