﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-&lt;h3&gt;Rookie&lt;/h3&gt;-随笔分类-J2EE</title><link>http://www.blogjava.net/Rookie/category/32851.html</link><description>&lt;h4&gt;Headache English&lt;/h4&gt;</description><language>zh-cn</language><lastBuildDate>Tue, 08 Jul 2008 03:20:00 GMT</lastBuildDate><pubDate>Tue, 08 Jul 2008 03:20:00 GMT</pubDate><ttl>60</ttl><item><title>google  搜索参数问题</title><link>http://www.blogjava.net/Rookie/archive/2008/01/18/176330.html</link><dc:creator>zhhang920</dc:creator><author>zhhang920</author><pubDate>Fri, 18 Jan 2008 13:01:00 GMT</pubDate><guid>http://www.blogjava.net/Rookie/archive/2008/01/18/176330.html</guid><wfw:comment>http://www.blogjava.net/Rookie/comments/176330.html</wfw:comment><comments>http://www.blogjava.net/Rookie/archive/2008/01/18/176330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Rookie/comments/commentRss/176330.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Rookie/services/trackbacks/176330.html</trackback:ping><description><![CDATA[<p>昨天弄servlet实现搜索引擎前端，发现google&nbsp;搜索参数有很多参数，不明白，大家来看看，知道的顺便告我一下；<br />
<br />
<a href="http://www.google.cn/search?complete=1&amp;hl=zh-CN&amp;newwindow=1&amp;q=google&amp;btnG=Google+%E6%90%9C%E7%B4%A2&amp;meta=&amp;aq=-1&amp;oq">http://www.google.cn/search?complete=1&amp;hl=zh-CN&amp;newwindow=1&amp;q=google&amp;btnG=Google+%E6%90%9C%E7%B4%A2&amp;meta=&amp;aq=-1&amp;oq</a>=</p>
<p><span style="color: red">complete<br />
hl：区域<br />
newwindow<br />
q：查询关键字<br />
btnG<br />
meta<br />
aq<br />
oq</span><br />
<br />
<a href="http://www.google.cn/search">http://www.google.cn/search</a>?会跳转到<a href="http://www.google.cn/webhp">http://www.google.cn/webhp</a>页面；<br />
<a href="http://www.google.cn/search">http://www.google.cn/search?q=123</a>就可以搜索，搞不懂；</p>
<p><br />
&nbsp;</p>
 <img src ="http://www.blogjava.net/Rookie/aggbug/176330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Rookie/" target="_blank">zhhang920</a> 2008-01-18 21:01 <a href="http://www.blogjava.net/Rookie/archive/2008/01/18/176330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SERVLET 学习(二) SERVLET技术概述</title><link>http://www.blogjava.net/Rookie/archive/2008/01/18/176327.html</link><dc:creator>zhhang920</dc:creator><author>zhhang920</author><pubDate>Fri, 18 Jan 2008 12:51:00 GMT</pubDate><guid>http://www.blogjava.net/Rookie/archive/2008/01/18/176327.html</guid><wfw:comment>http://www.blogjava.net/Rookie/comments/176327.html</wfw:comment><comments>http://www.blogjava.net/Rookie/archive/2008/01/18/176327.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/Rookie/comments/commentRss/176327.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Rookie/services/trackbacks/176327.html</trackback:ping><description><![CDATA[一，SERVLET 作用<br />
读取客户程序发送来的显式数据(表单数据)；<br />
读取客户程序发送来的隐式数据(请求报头)；<br />
生成相应的结果；<br />
发送显式的数据给客户程序（HTML）；<br />
发送隐式的数据给客户程序(状态代码和响应报头)；<br />
<br />
优点：高效，便利，功能强大，可移植性强，花费少，安全<br />
<br />
二，SERVLET 生命周期<br />
init：仅在servlet首次载入时执行一次。不是每次请求都要调用。<br />
service：在新线程中由服务器为每个请求而调用。发送到doGet，doPost等。不要覆盖这个方法！<br />
doGet, doPost, doXxx：处理GET, POST, 等请求。覆盖这些方法以提供期望的行为。<br />
destroy：在服务器删除servlet的实例时调用。不是每次请求后都调用。<br />
<br />
三，例子<br />
下面是看《Servlet与JSP核心编程第二版》测试例子；<br />
给大家推荐一个网站：<a href="http://chinesedocument.com/">http://chinesedocument.com/</a><br />
看名字就应该知道关于什么的了，上面东西挺多的，不错；<br />
<br />
说明：<br />
chapter2,chaper3:servlet基础，请求参数；<br />
chapter4：request请求头查看，post，get方式；<br />
chapter5: 简单搜索引擎前端，sendError，sendRedirect测试；测试用例：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;http://www.google.cn/search?q=&#8221;&nbsp;&nbsp;&nbsp; &#8220;sendRedirect&#8221;<br />
chapter6：ContentType测试<br />
chapter7：cookie测试，servlet:RegistrationForm 简单注册页面，，使用cookie的值预先填写表单的 字段，如果未找到相应的cookie则使用默认值；Registration servlet：基于接收到的请求参数创建cookie，如果得到所有的参数则显示这些值，如果任何参数缺失，则重定向到表单；<br />
chapter8：session实现一个简单购物车；流程：登陆（Login servlet）--商品列表（ShopForm servlet）&lt;----&gt;挑选（AddItem servlet）<br />
<br />
测试工程<a href="/Files/Rookie/servlet.rar">servlet.rar</a><br />
<br />
由于jar文件太大，工程中没有jar保，可自己添加；<br />
工程中用到有：servlet-api.jar，dom4j-1.6.1.jar，jaxen-1.1-beta-6.jar，pull-parser-2.1.10.jar，jaxme-api-0.3.jar，jsr173_1.0_api.jar，msv-20030807.jar，relaxngDatatype-20030807.jar，isorelax-20030108.jar，jtidy-4aug2000r7-dev.jar，xsdlib-20030807.jar，xpp3-1.1.3.3.jar<br />
由于购物车中用到了解析xml，所以Jar包一下就多了；<br />
<br />
购物车没有数据库，我用dom4j解析xml，然后把数据存放在session中，觉得很别扭；对dom4j不是很熟悉，解析那部分做的不好，大家给多提提意见；书中有个refresh例子，还没看明白；说看明白实现了给我发一份啊；
 <img src ="http://www.blogjava.net/Rookie/aggbug/176327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Rookie/" target="_blank">zhhang920</a> 2008-01-18 20:51 <a href="http://www.blogjava.net/Rookie/archive/2008/01/18/176327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SERVLET 学习(一) http协议</title><link>http://www.blogjava.net/Rookie/archive/2008/01/18/176314.html</link><dc:creator>zhhang920</dc:creator><author>zhhang920</author><pubDate>Fri, 18 Jan 2008 11:46:00 GMT</pubDate><guid>http://www.blogjava.net/Rookie/archive/2008/01/18/176314.html</guid><wfw:comment>http://www.blogjava.net/Rookie/comments/176314.html</wfw:comment><comments>http://www.blogjava.net/Rookie/archive/2008/01/18/176314.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/Rookie/comments/commentRss/176314.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Rookie/services/trackbacks/176314.html</trackback:ping><description><![CDATA[一，&nbsp;HTTP<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HTTP(Hypertext Transfer　Protocol, 超文本传输协议)，用于从WWW服务器传输超文本到本地浏览器的传输协议。你可以通过协议定制传送的内容，从而减少网络传输。HTTP协议是以TCP/IP为基础的高层协议。现在广泛使用的版本HTTP/1.1。<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;HTTP协议基于请求/响应模式(Request/Response).客户与服务器建立连接后，按照协议规定格式，发送请求到服务器，客户得到请求后，返回响应信息给客户。HTTP使用的端口号，通常为80。<br />
二，URL<br />
HTTP URL (包含了用于查找某个资源的足够的信息)的格式如下：<br />
<a href="http://host[%22:%22port][abs_path/">http://host[":"port][abs_path</a>]<br />
http表示要通过HTTP协议来定位网络资源；host表示合法的Internet主机域名或者IP地址；port指定一个端口号，为空则使用缺省端口80；abs_path指定请求资源的URI；如果URL中没有给出abs_path，那么当它作为请求URI时，必须以&#8220;/&#8221;的形式给出，通常这个工作浏览器自动帮我们完成。<br />
http://www.microsoft.com/china/index.htm。它的含义如下：<br />
1.http://：代表超文本传输协议，通知microsoft.com服务器显示Web页，通常不用输入；<br />
2.www：代表一个Web(万维网)服务器；<br />
3.Microsoft.com/：这是装有网页的服务器的域名，或站点服务器的名称；<br />
4.China/：为该服务器上的子目录，就好像我们的文件夹；<br />
5.Index.htm：index.htm是文件夹中的一个HTML文件(网页)。<br />
三，HTTP 工作原理<br />
　　HTTP协议是基于请求/响应范式的(相当于客户机/服务器)。一个客户机与服务器建立连接后，发送一个请求给服务器，请求方式的格式为：统一资源标识符(URL)、协议版本号，后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后，给予相应的响应信息，其格式为一个状态行，包括信息的协议版本号、一个成功或错误的代码，后边是MIME信息包括服务器信息、实体信息和可能的内容。<br />
　　许多HTTP通讯是由一个用户代理初始化的并且包括一个申请在源服务器上资源的请求。最简单的情况可能是在用户代理和服务器之间通过一个单独的连接来完成。在Internet上，HTTP通讯通常发生在TCP/IP连接之上。缺省端口是TCP80，但其它的端口也是可用的。但这并不预示着HTTP协议在Internet或其它网络的其它协协议之上才能完成。HTTP只预示着一个可靠的传输。<br />
　　这个过程就好像我们打电话订货一样，我们可以打电话给商家，告诉他我们需要什么规格的商品，然后商家再告诉我们什么商品有货，什么商品缺货。这些，我们是通过电话线用电话联系(HTTP是通过TCP/IP)，当然我们也可以通过传真，只要商家那边也有传真。<br />
四，HTTP 请求，应答组成<br />
<a href="http://www.cnpaf.net/Class/HTTP/0532918532641885.html">http://www.cnpaf.net/Class/HTTP/0532918532641885.html</a>
 <img src ="http://www.blogjava.net/Rookie/aggbug/176314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Rookie/" target="_blank">zhhang920</a> 2008-01-18 19:46 <a href="http://www.blogjava.net/Rookie/archive/2008/01/18/176314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2EE开发中字符处理</title><link>http://www.blogjava.net/Rookie/archive/2008/01/05/173000.html</link><dc:creator>zhhang920</dc:creator><author>zhhang920</author><pubDate>Sat, 05 Jan 2008 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/Rookie/archive/2008/01/05/173000.html</guid><wfw:comment>http://www.blogjava.net/Rookie/comments/173000.html</wfw:comment><comments>http://www.blogjava.net/Rookie/archive/2008/01/05/173000.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Rookie/comments/commentRss/173000.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Rookie/services/trackbacks/173000.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在java企业级开发中，会有多处涉及到字符集编码，有些地方需要进行正确的设置，有些地方需要进行一定程度的处理。<br />
<br />
<span style="font-size: 14pt">一，java中对字符的处理<br />
<p style="font-size: 14pt"><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: red">getBytes(charset)</span>：这是java字符串处理的一个标准函数，其作用是将字符串所表示的字符按照charset编码，并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文"，正常情况下（即没有错误的时候）存储为"4e2d 6587"，如果charset为"gbk"，则被编码为"d6d0 cec4"，然后返回字节"d6 d0 ce c4"。如果charset为"utf8"则最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1"，则由于无法编码，最后返回 "3f 3f"（两个问号）。<br />
</span><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: red">new String(charset)</span>：</span><span style="font-size: 12pt">这是java字符串处理的另一个标准函数，和上一个函数的作用相反，将字节数组按照charset编码进行组合识别<span style="font-size: 12pt">，最后转换为unicode存储。参考上述getBytes的例子，"gbk" 和"utf8"都可以得出正确的结果"4e2d 6587"，但iso8859-1最后变成了"003f 003f"（两个问号）。</span></span><span style="font-size: 12pt"><span style="font-size: 12pt">因为utf8可以用来表示/编码所有字符，所以new String( str.getBytes( "utf8" ), "utf8" ) == str，即完全可逆。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt"><span style="color: red"><span style="font-size: 12pt">setCharacterEncoding()</span></span>：</span><span style="font-size: 12pt">该函数用来设置http请求或者相应的编码。</span><span style="font-size: 12pt">对于request，是指提交内容的编码，指定后可以通过getParameter()则直接获得正确的字符串，如果不指定，则默认使用iso8859-1编码，需要进一步处理。参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前，不能执行任何getParameter()。java doc上说明：This method must be called prior to reading request parameters or reading input using getReader()。而且，该指定只对POST方法有效，对GET方法无效。分析原因，应该是在执行第一个getParameter()的时候，java将会按照编码分析所有的提交内容，而后续的getParameter()不再进行分析，所以setCharacterEncoding()无效。而对于GET方法提交表单是，提交的内容在URL中，一开始就已经按照编码分析所有的提交内容，setCharacterEncoding()自然就无效。</span><span style="font-size: 12pt">对于response，则是指定输出内容的编码，同时，该设置会传递给浏览器，告诉浏览器输出内容所采用的编码。<br />
</span><span style="font-size: 14pt"><br />
二，web开发中字符编码几处设置<br />
</span><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于web应用程序，和编码有关的设置或者函数如下。<br />
</span><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jsp编译：</span><span style="font-size: 12pt">指定文件的存储编码，很明显，该设置应该置于文件的开头。例如：&lt;@pagepageEncoding="GBK"%&gt;。另外，对于一般class文件，可以在编译的时候指定编码。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">jsp输出：</span><span style="font-size: 12pt">指定文件输出到browser是使用的编码，该设置也应该置于文件的开头。例如：&lt;%@ page contentType="text/html; charset= GBK" %&gt;。该设置和response.setCharacterEncoding("GBK")等效。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">meta设置：</span><span style="font-size: 12pt">指定网页使用的编码，该设置对静态网页尤其有作用。因为静态网页无法采用jsp的设置，而且也无法执行response.setCharacterEncoding()。例如：&lt;META http-equiv="Content-Type" content="text/html; charset=GBK" /&gt;，</span><span style="font-size: 12pt">如果同时采用了jsp输出和meta设置两种编码指定方式，则jsp指定的优先。因为jsp指定的直接体现在response中。</span><span style="font-size: 12pt">需要注意的是，apache有一个设置可以给无编码指定的网页指定编码，该指定等同于jsp的编码指定方式，所以会覆盖静态网页中的meta指定。所以有人建议关闭该设置。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">form设置：</span><span style="font-size: 12pt">当浏览器提交表单的时候，可以指定相应的编码。例如：&lt;form accept-charset= "gb2312"&gt;。一般不必不使用该设置，浏览器会直接使用网页的编码。<br />
</span><span style="font-size: 12pt"><span style="font-size: 14pt"><br />
三，URL地址</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL地址中含有中文字符是很麻烦的，前面描述过使用GET方法提交表单的情况，使用GET方法时，参数就是包含在URL中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL编码：对于URL中的一些特殊字符，浏览器会自动进行编码。这些字符除了"/?&amp;"等外，还包括unicode字符，比如汉子。这时的编码比较特殊。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">IE有一个选项"总是使用UTF-8发送URL"，当该选项有效时，IE将会对特殊字符进行UTF-8编码，同时进行URL编码。如果改选项无效，则使用默认编码"GBK"，并且不进行URL编码。但是，对于URL后面的参数，则总是不进行编码，相当于UTF-8选项无效。比如"中文.html?a=中文"，当UTF-8选项有效时，将发送链接"%e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87"；而UTF-8选项无效时，将发送链接"\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87"。注意后者前面的"中文"两个字只有4个字节，而前者却有18个字节，这主要时URL编码的原因。</span><span style="font-size: 12pt">当web server（tomcat）接收到该链接时，将会进行URL解码，即去掉"%"，同时按照ISO8859-1编码（上面已经描述，可以使用URLEncoding来设置成其它编码）识别。上述例子的结果分别是"\ue4\ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87"和"\u4e\u2d\u65\u87.html?a=\u4e\u2d\u65\u87"，注意前者前面的"中文"两个字恢复成了6个字符。这里用"\u"，表示是unicode。</span><span style="font-size: 12pt">所以，由于客户端设置的不同，相同的链接，在服务器上得到了不同结果。这个问题不少人都遇到，却没有很好的解决办法。所以有的网站会建议用户尝试关闭UTF-8选项。不过，下面会描述一个更好的处理办法。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">rewrite：</span><span style="font-size: 12pt">熟悉的人都知道，apache有一个功能强大的rewrite模块，这里不描述其功能。需要说明的是该模块会自动将URL解码（去除%），即完成上述web server（tomcat）的部分功能。有相关文档介绍说可以使用[NE]参数来关闭该功能，但我试验并未成功，可能是因为版本（我使用的是apache 2.0.54）问题。另外，当参数中含有"?&amp; "等符号的时候，该功能将导致系统得不到正常结果。</span><span style="font-size: 12pt">rewrite本身似乎完全是采用字节处理的方式，而不考虑字符串的编码，所以不会带来编码问题。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">URLEncode.encode()：</span><span style="font-size: 12pt">这是Java本身提供对的URL编码函数，完成的工作和上述UTF-8选项有效时浏览器所做的工作相似。值得说明的是，java已经不赞成不指定编码来使用该方法（deprecated）。应该在使用的时候增加编码指定。</span><span style="font-size: 12pt">当不指定编码的时候，该方法使用系统默认编码，这会导致软件运行结果得不确定。比如对于"中文"，当系统默认编码为"gb2312"时，结果是"%4e%2d%65%87"，而默认编码为"UTF-8"，结果却是"%e4%b8%ad%e6%96%87"，后续程序将难以处理。另外，这儿说的系统默认编码是由运行tomcat时的环境变量LC_ALL和LANG等决定的，曾经出现过tomcat重启后就出现乱码的问题，最后才郁闷的发现是因为修改修改了这两个环境变量。</span><span style="font-size: 12pt">建议统一指定为"UTF-8"编码，可能需要修改相应的程序。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">一个解决方案<br />
</span><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;上面说起过，因为浏览器设置的不同，对于同一个链接，web server收到的是不同内容，而软件系统有无法知道这中间的区别，所以这一协议目前还存在缺陷。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">针对具体问题，不应该侥幸认为所有客户的IE设置都是UTF-8有效的，也不应该粗暴的建议用户修改IE设置，要知道，用户不可能去记住每一个web server的设置。所以，接下来的解决办法就只能是让自己的程序多一点智能：根据内容来分析编码是否UTF-8。&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">比较幸运的是UTF-8编码相当有规律，所以可以通过分析传输过来的链接内容，来判断是否是正确的UTF-8字符，如果是，则以UTF-8处理之，如果不是，则使用客户默认编码（比如"GBK"），下面是一个判断是否UTF-8的例子，如果你了解相应规律，就容易理解</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;isValidUtf8(</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;b,</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;aMaxCount){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;lLen</span><span style="color: #000000">=</span><span style="color: #000000">b.length,lCharCount</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">lLen&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;lCharCount</span><span style="color: #000000">&lt;</span><span style="color: #000000">aMaxCount;</span><span style="color: #000000">++</span><span style="color: #000000">lCharCount){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">byte</span><span style="color: #000000">&nbsp;lByte</span><span style="color: #000000">=</span><span style="color: #000000">b[i</span><span style="color: #000000">++</span><span style="color: #000000">];</span><span style="color: #008000">//</span><span style="color: #008000">to&nbsp;fast&nbsp;operation,&nbsp;++&nbsp;now,&nbsp;ready&nbsp;for&nbsp;the&nbsp;following&nbsp;for(;;)</span><span style="color: #008000"><br />
</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(lByte</span><span style="color: #000000">&gt;=</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">continue</span><span style="color: #000000">;</span><span style="color: #008000">//</span><span style="color: #008000">&gt;=0&nbsp;is&nbsp;normal&nbsp;ascii</span><span style="color: #008000"><br />
</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(lByte</span><span style="color: #000000">&lt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xc0</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xf</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;lCount</span><span style="color: #000000">=</span><span style="color: #000000">lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xfc</span><span style="color: #000000">?</span><span style="color: #000000">5</span><span style="color: #000000">:lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xf8</span><span style="color: #000000">?</span><span style="color: #000000">4</span><span style="color: #000000"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xf0</span><span style="color: #000000">?</span><span style="color: #000000">3</span><span style="color: #000000">:lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xe0</span><span style="color: #000000">?</span><span style="color: #000000">2</span><span style="color: #000000">:</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(i</span><span style="color: #000000">+</span><span style="color: #000000">lCount</span><span style="color: #000000">&gt;</span><span style="color: #000000">lLen)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;j</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;j</span><span style="color: #000000">&lt;</span><span style="color: #000000">lCount;</span><span style="color: #000000">++</span><span style="color: #000000">j,</span><span style="color: #000000">++</span><span style="color: #000000">i)&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(b[i]</span><span style="color: #000000">&gt;=</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xc0</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">;<br />
<br />
}<br />
</span></div>
<p style="font-size: 14pt"></span><span style="font-size: 12pt">相应地，一个使用上述方法的例子如下：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;String&nbsp;getUrlParam(String&nbsp;aStr,String&nbsp;aDefaultCharset)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_105_284_Open_Image" onclick="this.style.display='none'; Codehighlighter1_105_284_Open_Text.style.display='none'; Codehighlighter1_105_284_Closed_Image.style.display='inline'; Codehighlighter1_105_284_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_105_284_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_105_284_Closed_Text.style.display='none'; Codehighlighter1_105_284_Open_Image.style.display='inline'; Codehighlighter1_105_284_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;UnsupportedEncodingException</span><span id="Codehighlighter1_105_284_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_105_284_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(aStr</span><span style="color: #000000">==</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;lBytes</span><span style="color: #000000">=</span><span style="color: #000000">aStr.getBytes(</span><span style="color: #000000">"</span><span style="color: #000000">ISO-8859-1</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;String(lBytes,StringUtil.isValidUtf8(lBytes)</span><span style="color: #000000">?</span><span style="color: #000000">"</span><span style="color: #000000">utf8</span><span style="color: #000000">"</span><span style="color: #000000">:aDefaultCharset);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p></span><span style="font-size: 12pt">不过，该方法也存在缺陷，如下两方面：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">没有包括对用户默认编码的识别，这可以根据请求信息的语言来判断，但不一定正确，因为我们有时候也会输入一些韩文，或者其他文字。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">可能会错误判断UTF-8字符，一个例子是"学习"两个字，其GBK编码是" \xd1\xa7\xcf\xb0"，如果使用上述isValidUtf8方法判断，将返回true。可以考虑使用更严格的判断方法，不过估计效果不大。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt">有一个例子可以证明google也遇到了上述问题，而且也采用了和上述相似的处理方法，比如，如果在地址栏中输入"http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习"，google将无法正确识别，而其他汉字一般能够正常识别。</span><span style="font-size: 12pt">最后，应该补充说明一下，如果不使用rewrite规则，或者通过表单提交数据，其实并不一定会遇到上述问题，因为这时可以在提交数据时指定希望的编码。另外，中文文件名确实会带来问题，应该谨慎使用。<br />
<span style="font-size: 12pt"><br />
<span style="font-size: 14pt">四，过滤器</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 12pt">如果需要统一设置编码，则通过filter进行设置是个不错的选择。在filter class中，可以统一为需要的请求或者回应设置编码。参加上述setCharacterEncoding()。这个类apache已经给出了可以直接使用的例SetCharacterEncodingFilter。</span></span></span></p>
  <img src ="http://www.blogjava.net/Rookie/aggbug/173000.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Rookie/" target="_blank">zhhang920</a> 2008-01-05 17:36 <a href="http://www.blogjava.net/Rookie/archive/2008/01/05/173000.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>