WebLucene 实现类似于Google 的多编码支持
2004-08-09 20:24
555 查看
当初在设计WebLucene 的时候,为了能够正确的截取请求中的中文q参数,在执行request.getParameter("q")之前先调用了request.setCharacterEncoding("gb2312")方法。这样虽然避免了乱码问题的出现,但却使得WebLucene 同时只能对一种编码进行处理,无法实现类似于Google 的搜索效果,例如下面两个链接:
http://www.google.com/search?ie=UTF-8&q=%E5%8C%97%E4%BA%AC
http://www.google.com/search?ie=gb2312&q=%B1%B1%BE%A9
查找的都是关键字为“北京”的内容,只是前者的 Url 是以UTF-8 方式进行UrlEncode 得的,而后者则采用的是Gb2312。
在Google 上查找了很多关于setCharacterEncoding 和“多语言支持” 的文章,最后还是用最古老的方法解决了问题,见下面一段代码:
String ie = request.getParameter("encoding");
String q = new String(request.getParameter("q").getBytes("ISO-8859-1"), ie);
这样,只要$q 是以$encodig 方式进行提交/UrlEncode 的,那么我们就可以得到正确的q参数了——但有一点需要注意,就是要用 “ISO-8859-1” 的形式对字符串q 进行getBytes() 操作,而不能采用Utf-8的形式(至少我目前的试验结果是这样的)。
之所以不能用UTF-8 是因为一些应用服务器,如resin2.*,在试图用UTF-8 编码解析参数的时候,往往会因为参数中含有了不合法的UTF-8 字符而产生异常,从而导致无法正常的解析参数。
稍后请见详细描述。
大家可以用我后面的程序作一个试验:
首先把resin的缺省编码设为UTF-8:
<log id='/' href='stderr:' timestamp="[%H:%M:%S.%s]"/>
<web-app character-encoding='UTF-8'>
....
<servlet>
<servlet-name>character</servlet-name>
<servlet-class>com.chedong.weblucene.CharacterEncodingTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>character</servlet-name>
<url-pattern>/character</url-pattern>
</servlet-mapping>
....
</web-app>
然后访问http://localhost:8080/weblucene/search?encoding=UTF-8&q=%E5%8C%97%E4%BA%AC,在resin 的log 中你会发现:
[19:10:52.484] java.io.CharConversionException: illegal utf8 encoding
at com.caucho.vfs.i18n.UTF8Reader.read(UTF8Reader.java:102)
at com.caucho.vfs.ByteToChar.readChar(ByteToChar.java:179)
at com.caucho.vfs.ByteToChar.getConvertedString(ByteToChar.java:126)
at com.caucho.server.http.Form.parseQueryString(Form.java:100)
at com.caucho.server.http.Request.parseQuery(Request.java:1352)
at com.caucho.server.http.Request.getParameterValues(Request.java:1449)
at com.caucho.server.http.Request.getParameter(Request.java:1459)
at com.chedong.weblucene.CharacterEncodingTest.doGet(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:126)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
at com.caucho.server.http.FilterChainServlet.doFilter(FilterChainServlet.java:96)
at com.caucho.server.http.Invocation.service(Invocation.java:315)
at com.caucho.server.http.CacheInvocation.service(CacheInvocation.java:135)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:246)
at com.caucho.server.http.HttpRequest.handleConnection(HttpRequest.java:163)
at com.caucho.server.TcpConnection.run(TcpConnection.java:139)
at java.lang.Thread.run(Thread.java:536)
附:
1.测试程序
http://www.google.com/search?ie=UTF-8&q=%E5%8C%97%E4%BA%AC
http://www.google.com/search?ie=gb2312&q=%B1%B1%BE%A9
查找的都是关键字为“北京”的内容,只是前者的 Url 是以UTF-8 方式进行UrlEncode 得的,而后者则采用的是Gb2312。
在Google 上查找了很多关于setCharacterEncoding 和“多语言支持” 的文章,最后还是用最古老的方法解决了问题,见下面一段代码:
String ie = request.getParameter("encoding");
String q = new String(request.getParameter("q").getBytes("ISO-8859-1"), ie);
这样,只要$q 是以$encodig 方式进行提交/UrlEncode 的,那么我们就可以得到正确的q参数了——但有一点需要注意,就是要用 “ISO-8859-1” 的形式对字符串q 进行getBytes() 操作,而不能采用Utf-8的形式(至少我目前的试验结果是这样的)。
之所以不能用UTF-8 是因为一些应用服务器,如resin2.*,在试图用UTF-8 编码解析参数的时候,往往会因为参数中含有了不合法的UTF-8 字符而产生异常,从而导致无法正常的解析参数。
稍后请见详细描述。
大家可以用我后面的程序作一个试验:
首先把resin的缺省编码设为UTF-8:
<log id='/' href='stderr:' timestamp="[%H:%M:%S.%s]"/>
<web-app character-encoding='UTF-8'>
....
<servlet>
<servlet-name>character</servlet-name>
<servlet-class>com.chedong.weblucene.CharacterEncodingTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>character</servlet-name>
<url-pattern>/character</url-pattern>
</servlet-mapping>
....
</web-app>
然后访问http://localhost:8080/weblucene/search?encoding=UTF-8&q=%E5%8C%97%E4%BA%AC,在resin 的log 中你会发现:
[19:10:52.484] java.io.CharConversionException: illegal utf8 encoding
at com.caucho.vfs.i18n.UTF8Reader.read(UTF8Reader.java:102)
at com.caucho.vfs.ByteToChar.readChar(ByteToChar.java:179)
at com.caucho.vfs.ByteToChar.getConvertedString(ByteToChar.java:126)
at com.caucho.server.http.Form.parseQueryString(Form.java:100)
at com.caucho.server.http.Request.parseQuery(Request.java:1352)
at com.caucho.server.http.Request.getParameterValues(Request.java:1449)
at com.caucho.server.http.Request.getParameter(Request.java:1459)
at com.chedong.weblucene.CharacterEncodingTest.doGet(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:126)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
at com.caucho.server.http.FilterChainServlet.doFilter(FilterChainServlet.java:96)
at com.caucho.server.http.Invocation.service(Invocation.java:315)
at com.caucho.server.http.CacheInvocation.service(CacheInvocation.java:135)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:246)
at com.caucho.server.http.HttpRequest.handleConnection(HttpRequest.java:163)
at com.caucho.server.TcpConnection.run(TcpConnection.java:139)
at java.lang.Thread.run(Thread.java:536)
附:
1.测试程序
package com.chedong.weblucene; import org.apache.log4j.Logger; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CharacterEncodingTest extends HttpServlet { //~ Static fields/initializers --------------------------------------------- /** The global logger, it will be configured when the servlet loaded */ private static Logger logger = Logger.getLogger(CharacterEncodingTest.class .getName() ); //~ Methods ---------------------------------------------------------------- public void destroy() { super.destroy(); } protected void doGet(HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException { //request.setCharacterEncoding("ISO-8859-1"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); System.out.println("i get a request, with encoding: " + request.getCharacterEncoding() + " "); String q = "empty"; if(request.getParameter("q") != null) { String ie = request.getParameter("ie"); if(ie == null) { ie = "gb2312"; } q = req 4000 uest.getParameter("q"); System.out.println("raw q:" + q + "."); q = new String(q.getBytes("iso-8859-1"), ie); System.out.println("parsed q with(" + ie + "):" + q); } else { q = "null"; Enumeration params = request.getParameterNames(); while(params.hasMoreElements()) { String param = (String) params.nextElement(); System.out.println("param: " + param + "-" + request.getParameter(param) + ". "); } } out.println(q); out.println(""); out.println(""); /* flush the buffer */ out.flush(); out.close(); } public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); } } |
相关文章推荐
- HTML5+Ajax+Jquery调用Google搜索API实现搜索引擎,支持web,image,news,vedio4种模式!
- JAVA_WEB项目之Lucene实现检索结果排序和关键字在索引库中多字段查询结果进行高亮显示
- 实现支持断点续传多线程下载的 Http Web 客户端工具类()
- Web UTF-8编码传给服务器后乱码:中英文支持技术方案
- .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient)
- java网络编程--解析通过web.xml文件控制利用过滤器实现编码格式步骤
- .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient)
- spring 对 timer 的支持---实现简单的web中定时器操作
- RFC3986编码 C 语言实现(支持大部分中文)
- JAVA_WEB项目之Spring中使用AOP编程运用到Lucene中实现解耦
- 支持多用户web终端实现及安全保障(nodejs)
- C#.Net: 实现支持断点续传多线程下载的 Http Web 客户端工具类
- 嵌入式 linux 智能设备应用中 web 支持的实现(二)
- 实现Google.cn Web方式下查询功能
- 嵌入式linux智能设备中web支持的实现(2)
- 即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】
- iOS实现向多个社交网站(facebook,微信,微博,twitter等)分享的代码,支持iPhone和iPAD(分享链接编码)
- android txt小说阅读器的实现(完美实现分页阅读,支持常见编码格式)
- spring 对 timer 的支持 实现简单的web中定时器操作
- Spring MVC+MediaElement.js实现在WEB上播放MP4并支持拖移播放