`
jaesonchen
  • 浏览: 313000 次
  • 来自: ...
社区版块
存档分类
最新评论

javaWeb中的编码解码

 
阅读更多

在上篇博客中LZ介绍了前面两种场景(IO、内存)中的Java编码解码操作,其实在这两种场景中我们只需要在编码解码过程中设置正确的编码解码方式一般而言是不会出现乱码的。对于我们从事java开发的人而言,其实最容易也是产生乱码最多的地方就是web部分。首先我们来看在javaWeb中有哪些地方存在编码转换操作。

编码&解码

通过下图我们可以了解在javaWeb中有哪些地方有转码:

201501060001

用户想服务器发送一个HTTP请求,需要编码的地方有url、cookie、parameter,经过编码后服务器接受HTTP请求,解析HTTP请求,然后对url、cookie、parameter进行解码。在服务器进行业务逻辑处理过程中可能需要读取数据库、本地文件或者网络中的其他文件等等,这些过程都需要进行编码解码。当处理完成后,服务器将数据进行编码后发送给客户端,浏览器经过解码后显示给用户。在这个整个过程中涉及的编码解码的地方较多,其中最容易出现乱码的位置就在于服务器与客户端进行交互的过程。

上面整个过程可以概括成这样,页面编码数据传递给服务器,服务器对获得的数据进行解码操作,经过一番业务逻辑处理后将最终结果编码处理后传递给客户端,客户端解码展示给用户。所以下面我就请求对javaweb的编码&解码进行阐述。

请求

客户端想服务器发送请求无非就通过四中情况:

1、URL方式直接访问。

2、页面链接。

3、表单get提交

4、表单post提交

URL方式

对于URL,如果该URL中全部都是英文的那倒是没有什么问题,如果有中文就要涉及到编码了。如何编码?根据什么规则来编码?又如何来解码呢?下面LZ将一一解答!首先看URL的组成部分:

201501060002

在这URL中浏览器将会对path和parameter进行编码操作。为了更好地解释编码过程,使用如下URL

http://127.0.0.1:8080/perbank/我是cm?name=我是cm

将以上地址输入到浏览器URL输入框中,通过查看http 报文头信息我们可以看到浏览器是如何进行编码的。下面是IE、Firefox、Chrome三个浏览器的编码情况:

201501080001

201501080002

201501080003

可以看到各大浏览器对“我是”的编码情况如下:

 

path部分

Query String

Firefox

E6 88 91 E6 98 AF

E6 88 91 E6 98 AF

Chrome

E6 88 91 E6 98 AF

E6 88 91 E6 98 AF

IE

E6 88 91 E6 98 AF

CE D2 CA C7

查阅上篇博客的编码可知对于path部分Firefox、chrome、IE都是采用UTF-8编码格式,对于Query String部分Firefox、chrome采用UTF-8,IE采用GBK。至于为什么会加上%,这是因为URL的编码规范规定浏览器将ASCII字符非 ASCII 字符按照某种编码格式编码成 16 进制数字然后将每个 16 进制表示的字节前加上“%”。

当然对于不同的浏览器,相同浏览器不同版本,不同的操作系统等环境都会导致编码结果不同,上表某一种情况,对于URL编码规则下任何结论都是过早的。由于各大浏览器、各个操作系统对URL的URI、QueryString编码都可能存在不同,这样对服务器的解码势必会造成很大的困扰,下面我们将已tomcat,看tomcat是如何对URL进行解码操作的。

解析请求的 URL 是在 org.apache.coyote.HTTP11.InternalInputBuffer 的 parseRequestLine 方法中,这个方法把传过来的 URL 的 byte[] 设置到 org.apache.coyote.Request 的相应的属性中。这里的 URL 仍然是 byte 格式,转成 char 是在 org.apache.catalina.connector.CoyoteAdapter 的 convertURI 方法中完成的在CODE上查看代码片派生到我的代码片

  1. protected void convertURI(MessageBytes uri, Request request)   
  2.              throws Exception {   
  3.                     ByteChunk bc = uri.getByteChunk();   
  4.                     int length = bc.getLength();   
  5.                     CharChunk cc = uri.getCharChunk();   
  6.                     cc.allocate(length, -1);   
  7.                     String enc = connector.getURIEncoding();     //获取URI解码集  
  8.                     if (enc != null) {   
  9.                         B2CConverter conv = request.getURIConverter();   
  10.                         try {   
  11.                             if (conv == null) {   
  12.                                 conv = new B2CConverter(enc);   
  13.                                 request.setURIConverter(conv);   
  14.                             }   
  15.                         } catch (IOException e) {...}   
  16.                         if (conv != null) {   
  17.                             try {   
  18.                                 conv.convert(bc, cc, cc.getBuffer().length - cc.getEnd());   
  19.                                 uri.setChars(cc.getBuffer(), cc.getStart(), cc.getLength());   
  20.                                 return;   
  21.                             } catch (IOException e) {...}   
  22.                         }   
  23.                     }   
  24.                     // Default encoding: fast conversion   
  25.                     byte[] bbuf = bc.getBuffer();   
  26.                     char[] cbuf = cc.getBuffer();   
  27.                     int start = bc.getStart();   
  28.                     for (int i = 0; i < length; i++) {   
  29.                         cbuf[i] = (char) (bbuf[i + start] & 0xff);   
  30.                     }   
  31.                     uri.setChars(cbuf, 0, length);   
  32.     }  

 

从上面的代码可知,对URI的解码操作是首先获取Connector的解码集,该配置在server.xml中

[java] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. <Connector URIEncoding="utf-8"  />  

 

如果没有定义则会采用默认编码ISO-8859-1来解析。

对于Query String部分,我们知道无论我们是通过get方式还是POST方式提交,所有的参数都是保存在Parameters,然后我们通过request.getParameter,解码工作就是在第一次调用getParameter方法时进行的。在getParameter方法内部它调用org.apache.catalina.connector.Request 的 parseParameters 方法,这个方法将会对传递的参数进行解码。下面代码只是parseParameters方法的一部分:

[java] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. //获取编码  
  2.    String enc = getCharacterEncoding();  
  3.   //获取ContentType 中定义的 Charset  
  4.   boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();  
  5.   if (enc != null) {    //如果设置编码不为空,则设置编码为enc  
  6.       parameters.setEncoding(enc);  
  7.       if (useBodyEncodingForURI) {   //如果设置了Chartset,则设置queryString的解码为ChartSet  
  8.           parameters.setQueryStringEncoding(enc);      
  9.       }  
  10.   } else {     //设置默认解码方式  
  11.       parameters.setEncoding(org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);  
  12.       if (useBodyEncodingForURI) {  
  13.           parameters.setQueryStringEncoding(org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);  
  14.       }  
  15.   }  

 

从上面代码可以看出对query String的解码格式要么采用设置的ChartSet要么采用默认的解码格式ISO-8859-1。注意这个设置的ChartSet是在 http Header中定义的ContentType,同时如果我们需要改指定属性生效,还需要进行如下配置:

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. <Connector URIEncoding="UTF-8" useBodyEncodingForURI="true"/>  

 

上面部分详细介绍了URL方式请求的编码解码过程。其实对于我们而言,我们更多的方式是通过表单的形式来提交。

表单GET

我们知道通过URL方式提交数据是很容易产生乱码问题的,所以我们更加倾向于通过表单形式。当用户点击submit提交表单时,浏览器会更加设定的编码来编码数据传递给服务器。通过GET方式提交的数据都是拼接在URL后面(可以当做query String??)来提交的,所以tomcat服务器在进行解码过程中URIEncoding就起到作用了。tomcat服务器会根据设置的URIEncoding来进行解码,如果没有设置则会使用默认的ISO-8859-1来解码。假如我们在页面将编码设置为UTF-8,而URIEncoding设置的不是或者没有设置,那么服务器进行解码时就会产生乱码。这个时候我们一般可以通过new String(request.getParameter("name").getBytes("iso-8859-1"),"utf-8") 的形式来获取正确数据。

表单POST

对于POST方式,它采用的编码也是由页面来决定的即contentType。当我通过点击页面的submit按钮来提交表单时,浏览器首先会根据ontentType的charset编码格式来对POST表单的参数进行编码然后提交给服务器,在服务器端同样也是用contentType中设置的字符集来进行解码(这里与get方式就不同了),这就是通过POST表单提交的参数一般而言都不会出现乱码问题。当然这个字符集编码我们是可以自己设定的:request.setCharacterEncoding(charset) 。


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

分享到:
评论

相关推荐

    JavaScript、JavaWeb对汉字等的编码与解码处理

    JavaScript和JavaWeb对汉字编码的策略是非常重要的,特别是在Web开发中,编码和解码的正确处理对于确保数据的正确传输和显示至关重要。在本资源中,我们将详细介绍JavaScript和JavaWeb对汉字编码的策略,包括escape...

    JavaWeb中过滤器的三个小案例

    例如,对于POST请求,可以使用HttpServletRequest的setCharacterEncoding方法设置UTF-8编码,对于GET请求,可能需要修改request的参数解析过程,确保正确的解码。这样,无论用户通过何种方式提交数据,都能避免中文...

    javaweb入门

    5. **Filter(过滤器)**:过滤器在JavaWeb中用于拦截请求和响应,实现预处理和后处理功能,如登录验证、数据编码解码等。了解过滤器的生命周期、配置以及如何编写自定义过滤器是必要的。 6. **Listener(监听器)*...

    JavaWeb登录注册页面

    此外,Filter还可以用来进行权限控制、URL编码解码、日志记录等多种用途。 MyBatis是Java的持久层框架,它简化了数据库操作,将SQL语句与Java代码分离,提供了一种基于XML或注解方式的映射配置,使得开发者能够更...

    JavaWeb开发技术-解决中文输出乱码问题.docx

    这个问题主要源于字符集(charset)的不匹配,即编码和解码过程中使用的字符集不同。为了解决这个问题,我们需要理解编码、解码过程以及如何在Servlet中正确地设置编码。 编码和解码是计算机处理字符的关键步骤。...

    javaweb乱码

    在Javaweb开发过程中,字符编码问题经常困扰着开发者,特别是中文等多字节字符的处理。本文将详细讲解如何全面解决Javaweb中的乱码问题,确保网页内容正确显示。 #### 一、配置服务器端编码 首先,我们需要确保...

    JAVAWEB照相带完整例子

    在JavaWeb应用中,当需要在网络上传输图片或者其它二进制数据时,base64编码是一个常用手段,因为它可以把二进制数据转化为ASCII字符串,方便在网络中传输。在这个例子中,`Base64.decode()`方法可能用于将前端传来...

    javaweb教程 PPT

    5. **过滤器(Filter)**: 过滤器允许在请求到达目标Servlet或JSP之前对其进行拦截和处理,例如,实现登录验证、数据编码解码、性能监控等功能。通过实现javax.servlet.Filter接口,开发者可以创建自定义过滤器。 6...

    javaweb项目中乱码的处理

    ### javaweb项目中乱码的处理 在Java Web项目的开发过程中,经常遇到的一个问题是字符乱码。这不仅影响用户体验,还可能导致数据错误。本文旨在详细介绍如何解决Java Web项目中的乱码问题,包括如何统一开发环境、...

    《JavaWeb程序开发进阶》-黑马程序员配套资源ppt.zip

    它允许我们在请求到达目标Servlet或JSP之前以及响应返回客户端之后进行预处理和后处理,例如实现登录检查、URL编码解码、字符编码转换等功能。 3. **第5章 Servlet事件监听器**:Servlet监听器允许我们监听容器中的...

    json数据base64编码压缩+解压解码(java以及js)

    java端:返回类型非字符接口调用StringUtils#base64AndCompressJson进行编码压缩 ,返回类型为字符接口调用StringUtils#base64Andcompress ...js 端:引入压缩包中的js文件 ,调用deBase64AndUncompress进行解压解码

    JavaWeb个人学习笔记

    JavaWeb是基于Java语言开发Web应用的一种技术体系,涉及众多组件和概念,包括HTTP协议、JSP、Servlet...通过这样的学习笔记,可以有效地帮助开发者对JavaWeb技术有更全面、深入的理解,从而在实际工作中更加得心应手。

    解决全站编码问题的javaWeb小项目

    在JavaWeb开发中,编码问题是一个常见的痛点,尤其是在处理用户输入、页面展示或者数据库存储时。本项目"解决全站编码问题的javaWeb小项目"旨在提供一套完整的解决方案,确保在项目的各个层面都能正确处理字符编码,...

    javaweb中Filter(过滤器)的常见应用

    本文将深入探讨javaweb中Filter的常见应用,以及如何解决全站字符编码问题。 首先,Filter是Java Servlet API的一部分,它遵循Servlet规范中的Filter接口。通过实现Filter接口并覆盖其`doFilter()`方法,开发者可以...

    javaweb开发高端培训

    4. Java代码处理:学习在Java代码中如何使用`new String()`构造函数、`getBytes()`和`new String(bytes, charset)`来正确处理字符串的编码和解码。 5. JSP与EL表达式:讲解在JSP页面中使用`&lt;meta&gt;`标签设置页面编码...

    javaweb课程设计报告1

    在订餐系统中,可能使用过滤器进行权限控制,比如验证用户登录状态,或者对请求和响应进行编码解码等操作。 5. **MVC开发模式**:MVC模式是一种将业务逻辑、数据和用户界面分离的设计模式。在这个项目中,Model代表...

    JavaWeb应用中文乱码的解决方案 (1).pdf

    这个问题主要源于字符编码的不一致,即不同的系统或组件使用了不同的字符集,导致数据在转换过程中出现混乱。以下是对JavaWeb应用中文乱码的详细解析及解决方案: 1. **原因分析**: - **HTTP请求头编码不明确**:...

    中文乱码javaWEB开发各种解决中文乱码问题

    中文字符的正确显示与处理涉及到编码、解码以及服务器配置等多个环节,若任一环节处理不当,都可能导致中文字符显示为乱码。本文将详细探讨Java Web开发中解决中文乱码问题的策略,包括文件编码设置、页面编码控制、...

Global site tag (gtag.js) - Google Analytics