[Miles' Blog]

Welcome 2 My Planet

Available categories: [/] [development. ~]

一个奇怪的中文编码问题的粗暴解决办法 [Permalink]

Fri Jan 21 08:14:45 CST 2005
Category [trouble shooting]

老系统中文编码有问题。如果不设置contentType为text/html; charset=gb2312,则虽然是html源文件是中文,但是需要更改IE的charset设置(这时候实际上察看http header看到的contentType是text/html; charset=iso8859-1);如果设置了contentType为gb2312,则html源里面的中文直接成了???。

这个老系统当时运行于jdk1.3+tomcat3下,当时就不知道是那根筋不对,怎么都搞不定,最后套了一个客户端包IE,强制了编码才掩盖了问题。现在3年多过去了,怎么也得长点本事吧?于是就开始想尽办法折腾。试过了所有的方法,包括设置filter,给html加所有相关的,甚至包括设置jb的默认字符集,都完全无效。实在气不过,甚至反编译了tomcat的HttpServletResponse、JspWriter等的实现代码,一时也没看出门道。。

最后,心一横,给问题定了性:不就是一个老系统么?咱不浪费那个时间,简单粗暴地解决问题就算搞完!下面就是暴力解决法:

public class HtmlMimeResponseWrapper extends HttpServletResponseWrapper {
  
  //....

  public PrintWriter getWriter() throws IOException {
    PrintWriter writer = super.getWriter();
    MyWriter myWriter = new MyWriter(writer);
    return myWriter;
  }

  //...
}
没错!就是用一个filter,把他的PrintWriter包裹起来。decorator里面decorate,哈哈。。PrintWriter是一个内部类,细节如下:
  class MyWriter extends PrintWriter {
    PrintWriter writer;

    public MyWriter(PrintWriter writer) {
      super(writer);
      this.writer = writer;
    }

    // 关键在这里!
    public void write(String buf) {
      String newbuf = null;
      try {
        newbuf = new String(buf.getBytes("iso-8859-1"));
      }
      catch (UnsupportedEncodingException ex) {
      }
      writer.write(newbuf);
    }

    public boolean checkError() {
      return writer.checkError();
    }

    public void print(Object obj) {
      writer.print(obj);
    }

    public void print(String s) {
      writer.print(s);
    }

    public void print(boolean b) {
      writer.print(b);
    }

    public void print(char c) {
      writer.print(c);
    }

    public void print(char[] s) {
      writer.print(s);
    }

    public void print(double d) {
      writer.print(d);
    }

    public void print(float f) {
      writer.print(f);
    }

    public void print(int i) {
      writer.print(i);
    }

    public void print(long l) {
      writer.print(l);
    }

    public void println() {
      writer.println();
    }

    public void println(Object x) {
      writer.println(x);
    }

    public void println(String x) {
      writer.println(x);
    }

    public void println(boolean x) {
      writer.println(x);
    }

    public void println(char x) {
      writer.println(x);
    }

    public void println(char[] x) {
      writer.println(x);
    }

    public void println(double x) {
      writer.println(x);
    }

    public void println(float x) {
      writer.println(x);
    }

    public void println(int x) {
      writer.println(x);
    }

    public void println(long x) {
      writer.println(x);
    }

    public void close() {
      writer.close();
    }

    public void flush() {
      writer.flush();
    }

    public void write(String str, int off, int len) {
      writer.write(str, off, len);
    }

    public void write(char[] cbuf) {
      writer.write(cbuf);
    }

    public void write(char[] cbuf, int off, int len) {
      String s=new String(cbuf, off, len);
      this.write(s);
    }

    public void write(int c) {
      writer.write(c);
    }
  }
现在把问题从头掐了。虽然粗暴了一点,不过效果达到了。对于那些没有时间深究,或者懒得深究的问题,用这样的方法还是不错的。

另外值得一提的是jb的Delegate member wizard功能。通过他可以快速的作出一个Wrapper类,不用把super class的方法都一个一个去机械的实现,很是省力。只不过以前的jb里,这个功能处于Wizard主菜单,而现在则藏到了Edit下。。害我一顿好找 /images/emoticons/sad.gif

Posted by: miles
Comments [0] |

?
四月 2024
Sun? Mon? Tue? Wed? Thu? Fri? Sat?
 123456
78910111213
14151617181920
21222324252627
282930    
       
<  Mar???Today??? May  >
<< <   1   > >>

Available categories: [/] [development. ~]

Powered By blojsom?? RSS Feed? RSS2 Feed? RDF Feed

html hits:?51246