当前位置: 移动技术网 > IT编程>开发语言>Java > java中文乱码之解决URL中文乱码问题的方法

java中文乱码之解决URL中文乱码问题的方法

2019年07月22日  | 移动技术网IT编程  | 我要评论
我们主要通过两种形式提交向服务器发送请求:url、表单。而表单形式一般都不会出现乱码问题,乱码问题主要是在url上面。通过前面几篇博客的介绍我们知道url向服务器发送请求编

我们主要通过两种形式提交向服务器发送请求: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 = '/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 = '/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 {
 private filterconfig config ;
 string encoding = null;
  public void destroy() {
  config = null; 
 } 
 public void dofilter(servletrequest request, servletresponse response,
   filterchain chain) throws ioexception, servletexception {
  request.setcharacterencoding(encoding);
  chain.dofilter(request, response); 
 }
 public void init(filterconfig config) throws servletexception {
  this.config = config;
  //获取配置参数 
  string str = config.getinitparameter("encoding");
  if(str!=null){
   encoding = str; 
  }
 }
}

配置:

 <filter>
  <filter-name>chineseencodingfilter-name> 
  <filter-class>
com.test.filter.characterencodingfilter-class> 
    <init-param>
   <param-name>encodingparam-name> 
   <param-value>utf-8param-value> 
  init-param> 
 filter> 
  <filter-mapping> 
  <filter-name>chineseencodingfilter-name> 
  <url-pattern>/*url-pattern>
 filter-mapping>

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

public class characterencoding implements filter {
 protected filterconfig filterconfig ;
 string encoding = null; 
  public void destroy() {
  this.filterconfig = null; 
 } 
 /** 
 * 初始化
  */ 
 public void init(filterconfig filterconfig) {
  this.filterconfig = filterconfig;
 } 
 /**
  * 将 instr 转为 utf-8 的编码形式
  *
  * @param instr 输入字符串
  * @return utf - 8 的编码形式的字符串
  * @throws unsupportedencodingexception
  */ 
 private string toutf(string instr) throws unsupportedencodingexception {
  string outstr = ""; 
  if (instr != null) { 
   outstr = new string(instr.getbytes("iso-8859-1"), "utf-8"); 
  } 
  return outstr; 
 } 
 /** 
 * 中文乱码过滤处理
  */
 public void dofilter(servletrequest servletrequest, 
   servletresponse servletresponse, filterchain chain) throws ioexception, 
   servletexception {
  httpservletrequest request = (httpservletrequest) servletrequest;
  httpservletresponse response = (httpservletresponse) servletresponse;
  // 获得请求的方式 (1.post or 2.get), 根据不同请求方式进行不同处理
  string method = request.getmethod(); 
  // 1. 以 post 方式提交的请求 , 直接设置编码为 utf-8 
  if (method.equalsignorecase("post")) {
   try {
    request.setcharacterencoding("utf-8");
   }
 catch (unsupportedencodingexception e) {
    e.printstacktrace(); 
   } 
  } 
  // 2. 以 get 方式提交的请求
  else {
   // 取出客户提交的参数集 
   enumeration paramnames = request.getparameternames(); 
   // 遍历参数集取出每个参数的名称及值
   while (paramnames.hasmoreelements()) {
    string name = paramnames.nextelement();// 取出参数名称 
    string values[] = request.getparametervalues(name);// 根据参数名称取出其值 
    // 如果参数值集不为空 
    if (values != null) {
     // 遍历参数值集 
     for (int i = 0; i < values.length; i++) {
      try {
     // 回圈依次将每个值调用 toutf(values[i]) 方法转换参数值的字元编码
       string vlustr = toutf(values[i]);
       values[i] = vlustr; 
      }
 catch (unsupportedencodingexception e) {
       e.printstacktrace(); 
      } 
    } 
     // 将该值以属性的形式藏在 request 
     request.setattribute(name, values);
    } 
   } 
  } 
  // 设置响应方式和支持中文的字元集
  response.setcontenttype("text/html;charset=utf-8");
  // 继续执行下一个 filter, 无一下个 filter 则执行请求
  chain.dofilter(request, response); 
 }
}

配置:

 
 <filter> 
  <filter-name>chineseencodingfilter-name> 
  <filter-class>com.test.filter.characterencodingfilter-class>
 filter> 
  <filter-mapping> 
  <filter-name>chineseencodingfilter-name>
  <url-pattern>/*url-pattern> 
 filter-mapping>

其他

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文件的标签中加上uriencoding=”utf-8″即可。

以上就是本文的全部内容,希望对大家学习java中文乱码问题有帮助

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网