WebLucene 实现类似于Google 的多编码支持

原创 2004年08月09日 20:24:00
当初在设计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.测试程序
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 = request.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);
    }
}

Google JavaScript 编码规范指南

JavaScript 语言规范 变量 link ▽ 声明变量必须加上 var 关键字. Decision: 当你没有写 var, 变量就会暴露在全局上下文中, 这样很可能会和现...
  • xianghongai
  • xianghongai
  • 2015年05月18日 20:04
  • 2719

Google的C++编码规范(总结)

本书分为几个大类别来阐述C++编码规范: --头文件 --作用域 --C++类 --智能指针和其他C++特性 --命名约定 --代码注释 --格式 --规则之例外 头...
  • some_times
  • some_times
  • 2014年08月03日 17:30
  • 743

google c++ 编码规范

1. 命名约定 最重要的一致性规则是命名管理. 命名风格快速获知名字代表是什么东东: 类型? 变量? 函数? 常量? 宏 ... ? 甚至不需要去查找类型声明. 我们大脑中的模式匹配引擎可以非常可靠...
  • xiexievv
  • xiexievv
  • 2016年03月24日 16:55
  • 6193

谷歌地图开发:地理编码和反地理编码

谷歌地图Geocoding说明:内容主要来自谷歌官网的文档,谷歌地图android api地理和反地理编码反应迟钝内容有时不准确,这里使用的googlemap的webapi接口。嗯,需要vpn这个不多...
  • xiaohui2015
  • xiaohui2015
  • 2017年02月10日 18:12
  • 1768

Google Geocoding API---地理编码与反向地理编码

什么是地理编码 地理编码是将地址(如“1600 Amphitheatre Parkway, Mountain View, CA”)转换为地理坐标(如纬度 37.423021 和经度 -122.0...
  • yyingwei
  • yyingwei
  • 2013年02月01日 10:45
  • 13679

Google 编码风格之命名规范(备忘)

参考链接:http://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/naming/ 通用规则:所有函数、...
  • Firehotest
  • Firehotest
  • 2016年07月22日 14:02
  • 3189

Java代码风格格式化和检查配置

1 说明 代码风格格式化和代码风格检查遵循Google代码风格。具体风格详见代码开发规范页。 2 code format eclipse-java-google-style.xml 模板(点击下...
  • yangchangyong0
  • yangchangyong0
  • 2016年05月28日 10:16
  • 1743

Python 编码风格指南中译版(Google SOC)

针对Python Style Guide Jun 18, 2009 版本翻译 译文发布于:http://www.elias.cn/Develop/PythonStyleGuide译者:elias...
  • damotiansheng
  • damotiansheng
  • 2015年02月17日 18:49
  • 2579

为什么Java不支持多继承?

我们知道Java不支持多继承,但这样的设计是出于什么考虑呢?
  • bigdata_wang
  • bigdata_wang
  • 2015年10月22日 19:46
  • 549

谷歌公司的C++编码风格

1. 头文件¶   通常每一个 .cc 文件都有一个对应的 .h 文件. 也有一些常见例外, 如单元测试代码和只包含 main() 函数的 .cc 文件.  正确使用头文件可令代码在可读性、文件...
  • Bro_J
  • Bro_J
  • 2017年03月15日 18:10
  • 245
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WebLucene 实现类似于Google 的多编码支持
举报原因:
原因补充:

(最多只允许输入30个字)