1. 有时候我们在处理 get 请求时,比如下面的一个 url 跳转

window.location.href = "某个 url"

当你的 url 里存在某个参数为中文字符,那么你就可能遇到乱码问题,为什么说可能呢,因为 tomcat 默认编码其实是 ISO-8859-1,如果你在 tomcat 服务器配置了 utf-8 编码的话(config 目录下的 server.xml 文件),就不会出乱码了,配置如下(注意在你的使用的端口里配置,一般都是在 8080 端口下配置一下 URIEncoding)

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>
  1. 现在我们不在服务器里做上面配置,那么就需要使用到 js 的编码技术以及 java.net 包提供的解码技术,首先比如说我们传的 url 里存在一个参数 departName=“教育 BG 研发中心”,那么我们调用 js 的方法进行编码 encodeURI (encodeURI (departName)),如下:
var departName = encodeURI(encodeURI(departName));
    window.location.href = "http://a.b.c?departName="+departName;

为什么做两次编码呢?

原因如下:

  1. 利用 encodeURI () 在 javascript 中对中文 URL 参数进行编码时,你的中文参数会被转换为类似于 “% E6% B5%8B% E8% AF%95” 这种字符串
  2. 但是浏览器机制会认为 “%” 是一个转义字符,浏览器会把地址栏 URL 中的传递的已转换参数 “%” 与 “%” 之间的已转义字符进行处理传递到后台 Action(接口)中。这样会造成与实际经过 encodeURI () 编码后的 URL 不符,因为浏览器误认为 “%” 是转义字符字符了,它并未将 “%” 认为是个普通字符。
  3. 要使得通过 encodeURI () 转换后的 URL 被浏览器正常处理,必须在外层再用 encodeURI () 处理一次已被 encodeURI () 编码后的 RUL。这此处理 encodeURI () 会将已编码后的 URL 中被浏览器解析为转义字符的 “%” 再次进行编码,转换为普通字符。

这个时候,在后台接口里使用 java.net 做一下转换就可以了:

String depName = java.net.URLDecoder.decode(request.getParameter("departName"), "UTF-8");

上面的转换方式是:js 前端转 2 次,后端转 1 次;

网上还有一种方式是:js 转一次,后端转 2 次,这个没有尝试,贴出来如下:

url=encodeURI(url)
String app_name = java.net.URLDecoder.decode(request.getParameter("name"), "utf-8");
app_name = new String(app_name.getBytes("ISO-8859-1"),"utf-8");
  1. 至于有些人疑惑 post 传递的参数里也有中文,为什么从前台传递过来不乱码呢?

原因是 post 是以数据包的形式将封装好的参数传递给后台,中间不会做编码转换相关的处理,所以后台直接获取也不会出现乱码。

当然有时 post 是会乱码的(比如使用 HttpClient 包下的工具,远程调用其它服务器的接口,偶尔会遇到这种乱码的情况),此时可以在接收时设置一下编码,如下几种方式:

1.java 代码里设置

request.setCharacterEncoding("UTF-8");
  1. 从 web 配置文件设置
<filter>
        <description>字符集过滤器</description>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
          <description>字符集编码</description>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
        </init-param>
     </filter>
     <filter-mapping>
      <filter-name>encodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
     </filter-mapping>
  1. 使用 HttpURLConnection 远程访问:
HttpURLConnection connection = null;
connection.setRequestProperty("contentType", "utf-8");
  1. 使用 InputStreamReader 读取流时
InputStreamReader in = null;
in = new InputStreamReader(connection.getInputStream(),"utf-8");
BufferedReader bufferedReader = new BufferedReader(in);
StringBuffer stringBuffer = new StringBuffer();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
    stringBuffer.append(line);
}
result = stringBuffer.toString();
  1. 使用 HttpClient 的 HttpGet 时
CloseableHttpClient httpclient = httpClientBuilder.build();
HttpGet httpget = new HttpGet("url");
CloseableHttpResponse response = httpclient.execute(httpget);
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
  1. 使用 HttpClient 的 HttpPost 时
CloseableHttpClient httpclient = httpClientBuilder.build();
HttpPost httpPost = new HttpPost(url);
List<BasicNameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("userAccount",userAccount));
params.add(new BasicNameValuePair("token",token));
UrlEncodedFormEntity httpEntity= new UrlEncodedFormEntity(valuePairs, "UTF-8");
httpMethod.setEntity(httpEntity);
CloseableHttpResponse response = httpclient.execute(httpMethod);
String content = EntityUtils.toString(response.getEntity(), "UTF-8");

具体前端 js 编码的使用说明可以参考 w3c 的文档:http://www.w3school.com.cn/jsref/jsref_encodeuri.asp

语法:encodeURI (URIstring)

参数 URIstring 描述:必需。一个字符串,含有 URI 或其他要编码的文本。

返回值:URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。

说明:

  1. 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。
  2. 该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI () 函数是不会进行转义的:;/?😡&=+$,#

提示和注释:如果 URI 组件中含有分隔符,比如?和 #,则应当使用 encodeURIComponent () 方法分别对各组件进行编码。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Jalen Chu 微信支付

微信支付

Jalen Chu 支付宝

支付宝

Jalen Chu 公众号

公众号