form表单提交数据编码方式和tomcat接受数据解码方式的思考

Tomcat浏览器Servlet.net读书 
做java的web开发有段日子了,有个问题老是困扰着我,就是乱码问题,基本上是网上查找解决方案(网上资料真的很多),都是一大堆的介绍如何解决此类的乱码问题,但是没几个把问题的来龙去脉说清楚的,有时候看了些文章后,以为自己懂了,但是在开发中乱码问题又像鬼魂一样出来吓人,真是头大了!这篇文章是我长时间和乱码做斗争的一些理解的积累,还希望有更多的朋友给出指点和补充。 
  form有2中方法把数据提交给服务器,get和post,分别说下吧。 
(一)get提交 
  1.首先说下客户端(浏览器)的form表单用get方法是如何将数据编码后提交给服务器端的吧。 
   
    对于get方法来说,都是把数据串联在请求的url后面作为参数,如:http://localhost:8080/servlet?msg=abc 
(很常见的一个乱码问题就要出现了,如果url中出现中文或其它特殊字符的话,如:http://localhost:8080/servlet?msg=杭州,服务器端容易得到乱码),url拼接完成后,浏览器会对url进行URL encode,然后发送给服务器,URL encode的过程就是把部分url做为字符,按照某种编码方式(如:utf-8,gbk等)编码成二进制的字节码,然后每个字节用一个包含3个字符的字符串 "%xy" 表示,其中xy为该字节的两位十六进制表示形式。我这里说的可能不清楚,具体介绍可以看下java.net.URLEncoder类的介绍在这里。了解了URL encode的过程,我们能看到2个很重要的问题,第一:需要URL encode的字符一般都是非ASCII的字符(笼统的讲),再通俗的讲就是除了英文字母以外的文字(如:中文,日文等)都要进行URL encode,所以对于我们来说,都是英文字母的url不会出现服务器得到乱码问题,出现乱码都是url里面带了中文或特殊字符造成的;第二:URL encode到底按照那种编码方式对字符编码?这里就是浏览器的事情了,而且不同的浏览器有不同的做法,中文版的浏览器一般会默认的使用GBK,通过设置浏览器也可以使用UTF-8,可能不同的用户就有不同的浏览器设置,也就造成不同的编码方式,所以很多网站的做法都是先把url里面的中文或特殊字符用javascript做URL encode,然后再拼接url提交数据,也就是替浏览器做了URL encode,好处就是网站可以统一get方法提交数据的编码方式。 完成了URL encode,那么现在的url就成了ASCII范围内的字符了,然后以iso-8859-1的编码方式转换成二进制随着请求头一起发送出去。这里想多说几句的是,对于get方法来说,没有请求实体,含有数据的url都在请求头里面,之所以用URL encode,我个人觉的原因是:对于请求头来说最终都是要用iso-8859-1编码方式编码成二进制的101010.....的纯数据在互联网上传送,如果直接将含有中文等特殊字符做iso-8859-1编码会丢失信息,所以先做URL encode是有必要的。 
   2。服务器端(tomcat)是如何将数据获取到进行解码的。 
   第一步是先把数据用iso-8859-1进行解码,对于get方法来说,tomcat获取数据的是ASCII范围内的请求头字符,其中的请求url里面带有参数数据,如果参数中有中文等特殊字符,那么目前还是URL encode后的%XY状态,先停下,我们先说下开发人员一般获取数据的过程。通常大家都是request.getParameter("name")获取参数数据,我们在request对象或得的数据都是经过解码过的,而解码过程中程序里是无法指定,这里要说下,有很多新手说用request.setCharacterEncoding("字符集")可以指定解码方式,其实是不可以的,看servlet的官方API说明有对此方法的解释:Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().可以看出对于get方法他是无能为力的。那么到底用什么编码方式解码数据的呢,这是tomcat的事情了,默认缺省用的是iso-8859-1,这样我们就能找到为什么get请求带中文参数为什么在服务器端得到乱码了,原因是在客户端一般都是用UTF-8或GBK对数据URL encode,这里用iso-8859-1方式URL decoder显然不行,在程序里我们可以直接

Java代码  
  1. new String(request.getParameter("name").getBytes("iso-8859-1"),"客户端指定的URL encode编码方式")

还原回字节码,然后用正确的方式解码数据,网上的文章通常是在tomcat里面做个配置

Xml代码  
  1. <Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK"/>

这样是让tomcat在获取数据后用指定的方式URL decoder,URL decoder的介绍在这里

(一)post提交 
1.客户端(浏览器)的form表单用post方法是如何将数据编码后提交给服务器端的。 
  在post方法里所要传送的数据也要URL encode,那么他是用什么编码方式的呢? 
   在form所在的html文件里如果有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>,那么post就会用此处指定的编码方式编码。一般大家都认为这段代码是为了让浏览器知道用什么字符集来对网页解释,所以网站都会把它放在html代码的最前端,尽量不出现乱码,其实它还有个作用就是指定form表单的post方法提交数据的URL encode编码方式。从这里可以看出对于get方法来数,浏览器对数据的URL encode的编码方式是有浏览器设置来决定,(可以用js做统一指定),而post方法,开发人员可以指定。 
2。服务器端(tomcat)是如何将数据获取到进行解码的。 
如果用tomcat默认缺省设置,也没做过滤器等编码设置,那么他也是用iso-8859-1解码的,但是request.setCharacterEncoding("字符集")可以派上用场。

我发现上面说的tomcat所做的事情前提都是在请求头里没有指定编码方式,如果请求头里指定了编码方式将按照这种方式编码。 
   有2篇文章推荐下,地址分别是 
http://www.cnblogs.com/yencain/articles/1321386.html; 
http://wanghuan8086.iteye.com/blog/173869

分享到:  
预测2010年中国经济: 1.资产泡沫化 2.经 ... | 会话cookie和持久化cookie实现session机制
  • 2008-11-13 17:31
  • 浏览 4470
  • 评论(13)
  • 论坛回复 / 浏览 (12 / 19902)
  • 分类:企业架构
  • 查看更多
相关资源推荐
  • 迅捷全站功能模块
  • 自定义bootstrap样式-9行样式自定义漂亮大气bootstrap导航栏
  • 自定义bootstrap导航栏
  • 精通Linux 第2版
  • 循序渐进Linux 第2版.part4
  • 循序渐进Linux 第2版.part3
  • 循序渐进Linux 第2版.part2
  • 循序渐进linux:全版
  • 循序渐进linux_PDF
  • 智慧的大数据企业架构蓝图2.1
  • 智慧大数据的企业架构蓝图2.0
  • 大数据运营-服务型企业架构新思维
  • 企业架构中实施大数据解决方案
  • 林业电子政务信息系统企业架构框架总体设计.pdf
  • Togaf9 企业架构框架英文版
  • 企业架构转型重构的若干治理问题洞察-官华
  • 企业架构语言ArchiMate+v0.5
  • Sun认证企业架构师 学习书籍
  • 2小时初探企业架构TOGAF
  • TOGAF企业架构框架白皮书
参考知识库
Android知识库37704  关注 | 3152  收录
React知识库3588  关注 | 393  收录
人工智能基础知识库16607  关注 | 212  收录
Java 知识库34998  关注 | 3748  收录
评论
13 楼 zchaony 2009-10-14  
filter

12 楼 czwlucky 2009-10-13  
不知道大家有没有遇到这样的参数?
http://aa.com?name&age=abc99
这里是希望name&age是key,abc99是值,像这样的参数如何处理才正确呢?
我现在遇到的问题出在webwork的使用上,它使用ognl自动组装参数到对象,但遇到这样的参数时会抛异常。

11 楼 jieyuan_cg 2009-07-05  
解决get方法提交参数乱码问题的关键:在页面response回去之前,如果页面中的url里面带有中文字符,就一定把这个中文字符进行编码。经过编码后的字符串都类似于%xy,不管浏览器用什么方法encode,都不会出错。

10 楼 xukejun_BabyY 2009-06-16  
谢谢分享,有了进一步的理解!!

9 楼 jiongerher 2009-03-02  
rubyeye 写道
在程序里我们可以直接

Java代码  
  1. new String(request.getParameter("name").getBytes("iso-8859-1"),"客户端指定的URL encode编码方式")

请问楼主,我这样理解是否对:

tomcat的解码过程是  解码+解释 
tomcat默认是在解码后用ISO8859-1进行解释。 无论给tomcat指定何种URIEncoding方式,实际上都能真确解码,只不过解码后的解释可能会应为设置的URIEncoding,而解释不正确。

所以request.getParameter("name")已经拿到了解码的结果,只是解释的不对。这样理解对吗?

8 楼 asuperfly 2008-12-18  
我的读书笔记:URLDecoder 
用post很重要的在form所在的html文件里如果有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/> 
强烈建议使用post提交

7 楼 rubyeye 2008-12-12  
hyogacs 写道

提交的方式就是这样的:http://localhost:8080/Action?name=大连,这样里面的参数值“大连”默认是用GBK编码方式传到Action这个servlet的,我想知道怎么能在servlet里面得到“大连”这个值。get方法也许是我理解的不对,说的不好,总之意思就是跟在请求后面用?传递参数。

从你的情况看,你的tomcat配置了URIEncoding="UTF-8",并且你可以肯定数据是通过GBK字符集URLEncoder的,那么用你试过的new String(request.getParameter("name").getBytes("UTF-8"),"GBK"))方式就能取到正确的数据。
所以我也不好说了,你再检查下你的数据是通过GBK字符集URLEncoder的吗?

6 楼 hyogacs 2008-12-11  
提交的方式就是这样的:http://localhost:8080/Action?name=大连,这样里面的参数值“大连”默认是用GBK编码方式传到Action这个servlet的,我想知道怎么能在servlet里面得到“大连”这个值。get方法也许是我理解的不对,说的不好,总之意思就是跟在请求后面用?传递参数。

5 楼 rubyeye 2008-12-07  
hyogacs 写道

有个用GET传递参数的问题。想问一下LZ,就是我在tomcat配置了 URIEncoding="UTF-8",我在我的页面将我的中文信息用java.net.URLEncoder.encode("大连","UTF-8")编码后,在servlet里面request.getParameter("name")可以得到正确的中文信息大连。如果默认提交的话,我发现我的浏览器是用GBK编码后发给服务器的,即与java.net.URLEncoder.encode("大连","GBK")效果相同。现在的问题是我的tomcat配置文件不变的情况下,我能否在jsp页面不处理,即用默认的gbk编码方式传到servlet,而在servlet中取到正确的值呢?如果能,请问怎么取?(我试过new String(request.getParameter("name").getBytes("UTF-8"),"GBK")),取不到)。先提前谢谢lz

用你的方法取不到值是有点奇怪了,你的get方法是怎么带参数的呢?
在http://www.cnblogs.com/yencain/articles/1321386.html文章里面提到:
http://localhost:8080/大连?name=大连
上面的URL里面,前一个大连和后一个大连的URLEncoder是不一样,你是怎么带参数的呢?

4 楼 hyogacs 2008-11-28  
有个用GET传递参数的问题。想问一下LZ,就是我在tomcat配置了 URIEncoding="UTF-8",我在我的页面将我的中文信息用java.net.URLEncoder.encode("大连","UTF-8")编码后,在servlet里面request.getParameter("name")可以得到正确的中文信息大连。如果默认提交的话,我发现我的浏览器是用GBK编码后发给服务器的,即与java.net.URLEncoder.encode("大连","GBK")效果相同。现在的问题是我的tomcat配置文件不变的情况下,我能否在jsp页面不处理,即用默认的gbk编码方式传到servlet,而在servlet中取到正确的值呢?如果能,请问怎么取?(我试过new String(request.getParameter("name").getBytes("UTF-8"),"GBK")),取不到)。先提前谢谢lz

3 楼 ddd0401 2008-11-22  
对这问题一直一知半懂的,多谢分享,thinks

2 楼 usherlight 2008-11-21  
good.

1 楼 chhg58 2008-11-21  
对get post 又有了进一步的了解

form表单提交数据编码方式和tomcat接受数据解码方式的思考相关推荐

  1. form表单提交数据编码方式和tomcat接受数据解码方式

    2019独角兽企业重金招聘Python工程师标准>>> 简单介绍乱码和http请求 1)  乱码问题是web开发过程中经常遇到的问题,主要原因就是URL中使用了非ASCII码造成服务 ...

  2. Form表单提交前进行JS验证的3种方式

    1. 提交按钮的onclick事件中验证 <script type="text/javascript">          function check(form) { ...

  3. ajax form表单提交_开发日志:金数据表单自动提交脚本

    最近学校要求我们每天通过一个在线表单打卡自己在家做的体育课项目,在提交的时候我突然想了下如果能有一个自动的系统每天帮我自动打卡岂不是能省很多时间?而且我一直很想学Python的网络爬虫以及服务器后端的 ...

  4. html 提交form表单提交数据格式,form表单提交数据

    form表单提交的几种方法 HTML表单提交的几种方式方式一:通过submit按钮提交方式二:通过一般按钮button提交1/3javascript">functionsubmit1( ...

  5. 传统form表单提交方式的文件上传与文件存储

    引言 时隔一天,上一篇文章<文件存储>刚一停笔,今天上午就解决了困扰我已久的文件上传问题. 站在一个已实现功能的角度来重新看待这个文件上传的业务:编辑页面选择jar包,然后通过form表单 ...

  6. form表单提交带参数的两种方式

    #第一种方式# action写明了LoginServlet,通过submit按钮直接提交到后台 <form action="LoginServlet" method=&quo ...

  7. 常见的Form表单提交方式

    Form表单提交方式探究 在进行项目编程的时候,我们难免会去编写一些简单的前端页面. 而编写前端页面就力不开 form表单的支持. 下面就form表单的提交方式进行如下探寻 1.常规写法 在form表 ...

  8. SSM框架下实现form表单提交的方式

    实现form表单的提交有多种方式,这里我们主要讲两种常用的. 注:此Demo是在SSM框架下完成的,数据库采用MySQL,关于ssm整合的相关知识,这里不做过多赘述.主要展示表单提交方式,暂不考虑代码 ...

  9. php form表单提交方式,form表单提交数据的几种方式

    一.submit提交 一般表单提交通过type=submit实现,input type="submit",浏览器显示为button按钮,通过点击这个按钮提交表单数据跳转到/url. ...

  10. form表单提交数据到后台的方式

    form表单提交方式 1.无刷新页面提交表单 表单可实现无刷新页面提交,无需页面跳转,如下,通过一个隐藏的iframe实现,form表单的target设置为iframe的name名称, form提交目 ...

最新文章

  1. “区块链”究竟是什么
  2. Dubbo设置超时时间
  3. Python基础教程:变量和注释
  4. 数据库的使用你可能忽略了这些 (续)
  5. Fiori Elements value help的工作原理
  6. Java JDK 10会有什么期望
  7. 实战 Nginx 与 PHP(FastCGI)的安装、配置与优化
  8. paypal支付详细指南:基于PayPal-PHP-SDK进行接口对接
  9. 外挂学习之路(10)--- 穿透发包线程寻找call的通杀方法
  10. 数据库中的二维表—巧借Excel
  11. 美国10大计算机软件,美国计算机软件工程专业研究生排名
  12. 计算机用户界面的设计,计算机软件用户界面设计的基本原则
  13. 【MySQL】InnoDB存储引擎
  14. Android+6.0的全盘加密(,Android6.0强制全盘加密 隐私牺牲性能
  15. oracle opm系统,ORACLE EBS OPM标准功能培训资料-OPM成本-V1.0.doc
  16. php和mhp,达人专业评测容声BDBC-516MHP质量怎么样呢?评测好不好?老铁吐露实情...
  17. 7-3 接话茬 (100分)(简洁易懂的代码含思路分析)
  18. 关于数字档案馆建设实践与思考
  19. java pkcs7_使用PKCS#7进行加密解密
  20. 通告 | Eth2 验证者快速启动器发布

热门文章

  1. Linux系统彻底卸载MySQL数据库
  2. “舒尔特表”训练法:产生1-25随机数,并打印到一个表格中
  3. 计算机应用离散数学,结合计算机应用的离散数学教学研究.pdf
  4. ad09只在一定范围内查找相似对象_AD常用快捷键
  5. bat批处理命令详解
  6. char、int、long、float、double等在64位下占多少字节
  7. 一个非常强大的静态导航网站nav
  8. 5万字 | 2020大厂面试总结,PDF供下载
  9. java从地址串中解析提取省市区-完美匹配中国所有地址
  10. 计算机软件行业各职位英文缩写