java中文输出乱码_java汉字乱码解决办法

java中文输出乱码_java汉字乱码解决办法自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。一、Java中文问题的由来Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。首先Java(包括J…

大家好,又见面了,我是你们的朋友全栈君。

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 或 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char  从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char  从java程序到数据库   char—> byte

从文件到java程序   byte-> char  从java程序到文件   char-> byte

从流到java程序   byte-> char  从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码  JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( “GBK “)或request.setCharacterEncoding( “gb2312 “)。  如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType( “text/html;charset=GBK “)或response.setContentType( “text/html;charset=gb2312 “)解决。  如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:  web.xml:

  CharacterEncodingFilter   net.vschool.web.CharacterEncodingFilter     encoding   GBK         CharacterEncodingFilter   /*  

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter    {

protected   String   encoding   =   null;

public   void   init(FilterConfig   filterConfig)   throws   ServletException    {  this.encoding   =   filterConfig.getInitParameter( “encoding “);  }

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException    {  request.setCharacterEncoding(encoding);  response.setContentType( “text/html;charset= “+encoding);  chain.doFilter(request,   response);  }

}

2、Java与数据库之间的乱码  大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java与文件/流之间的乱码  Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。

4、其他  上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1   );  改成了  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1,   charset   );  终于解决了这个乱码问题。

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 或 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char  从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char  从java程序到数据库   char—> byte

从文件到java程序   byte-> char  从java程序到文件   char-> byte

从流到java程序   byte-> char  从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码  JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( “GBK “)或request.setCharacterEncoding( “gb2312 “)。  如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType( “text/html;charset=GBK “)或response.setContentType( “text/html;charset=gb2312 “)解决。  如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:  web.xml:

  CharacterEncodingFilter   net.vschool.web.CharacterEncodingFilter     encoding   GBK         CharacterEncodingFilter   /*  

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter    {

protected   String   encoding   =   null;

public   void   init(FilterConfig   filterConfig)   throws   ServletException    {  this.encoding   =   filterConfig.getInitParameter( “encoding “);  }

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException    {  request.setCharacterEncoding(encoding);  response.setContentType( “text/html;charset= “+encoding);  chain.doFilter(request,   response);  }

}

2、Java与数据库之间的乱码  大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java与文件/流之间的乱码  Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。

4、其他  上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1   );  改成了  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1,   charset   );  终于解决了这个乱码问题。

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 或 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char  从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char  从java程序到数据库   char—> byte

从文件到java程序   byte-> char  从java程序到文件   char-> byte

从流到java程序   byte-> char  从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码  JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( “GBK “)或request.setCharacterEncoding( “gb2312 “)。  如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType( “text/html;charset=GBK “)或response.setContentType( “text/html;charset=gb2312 “)解决。  如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:  web.xml:

  CharacterEncodingFilter   net.vschool.web.CharacterEncodingFilter     encoding   GBK         CharacterEncodingFilter   /*  

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter    {

protected   String   encoding   =   null;

public   void   init(FilterConfig   filterConfig)   throws   ServletException    {  this.encoding   =   filterConfig.getInitParameter( “encoding “);  }

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException    {  request.setCharacterEncoding(encoding);  response.setContentType( “text/html;charset= “+encoding);  chain.doFilter(request,   response);  }

}

2、Java与数据库之间的乱码  大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java与文件/流之间的乱码  Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。

4、其他  上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1   );  改成了  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1,   charset   );  终于解决了这个乱码问题。

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 或 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char  从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char  从java程序到数据库   char—> byte

从文件到java程序   byte-> char  从java程序到文件   char-> byte

从流到java程序   byte-> char  从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码  JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( “GBK “)或request.setCharacterEncoding( “gb2312 “)。  如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType( “text/html;charset=GBK “)或response.setContentType( “text/html;charset=gb2312 “)解决。  如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:  web.xml:

  CharacterEncodingFilter   net.vschool.web.CharacterEncodingFilter     encoding   GBK         CharacterEncodingFilter   /*  

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter    {

protected   String   encoding   =   null;

public   void   init(FilterConfig   filterConfig)   throws   ServletException    {  this.encoding   =   filterConfig.getInitParameter( “encoding “);  }

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException    {  request.setCharacterEncoding(encoding);  response.setContentType( “text/html;charset= “+encoding);  chain.doFilter(request,   response);  }

}

2、Java与数据库之间的乱码  大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java与文件/流之间的乱码  Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。

4、其他  上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1   );  改成了  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1,   charset   );  终于解决了这个乱码问题。

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上  或  基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char  从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char  从java程序到数据库   char—> byte

从文件到java程序   byte-> char  从java程序到文件   char-> byte

从流到java程序   byte-> char  从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码  JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( “GBK “)或request.setCharacterEncoding( “gb2312 “)。  如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType( “text/html;charset=GBK “)或response.setContentType( “text/html;charset=gb2312 “)解决。  如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:  web.xml:

  CharacterEncodingFilter   net.vschool.web.CharacterEncodingFilter     encoding   GBK         CharacterEncodingFilter   /*  

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter    {

protected   String   encoding   =   null;

public   void   init(FilterConfig   filterConfig)   throws   ServletException    {  this.encoding   =   filterConfig.getInitParameter( “encoding “);  }

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException    {  request.setCharacterEncoding(encoding);  response.setContentType( “text/html;charset= “+encoding);  chain.doFilter(request,   response);  }

}

2、Java与数据库之间的乱码  大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java与文件/流之间的乱码  Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。

4、其他  上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1   );  改成了  String   value   =   new   String(m_binArray,   m_startData,   (m_endData   –   m_startData)   +   1,   charset   );  终于解决了这个乱码问题。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156191.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • b4什么意思_f0是什么车

    b4什么意思_f0是什么车AndroidEagleEyeAnXposedandadbibasedmodulewhichiscapableofhookingbothJavaandNativemethodstargetingAndroidOS.Relatedinformationofthehookedmethodswillbeloggedastheoutput.Us…

  • 联想笔记本电脑键盘灯在哪里开_笔记本电脑键盘字母键变成数字键

    联想笔记本电脑键盘灯在哪里开_笔记本电脑键盘字母键变成数字键在联想系列的笔记本电脑中,自带有键盘等的功能,不仅可以显得炫酷,还可以在光线比较暗的情况下打开键盘灯可以方便我们看清键盘上的按键,不过很多用户并不知道联想的键盘灯怎么开吧,其实有快捷键可以快速开启的,下面就给大家分享一下联想笔记本键盘亮灯按哪个键吧。具体步骤如下:1、联想笔记本部分型号具bai备键盘背光功能,方法通du过“FN+空格”打开,支持此功能的zhi机型,dao键盘上有相应标示。部分早期的…

  • 鼠标捕获(setCapture,releaseCapture)的学习

    鼠标捕获(setCapture,releaseCapture)的学习鼠标捕获(setCapture)作用是将鼠标事件捕获到当前文档的指定的对象——对指定的对象设置鼠标捕获。这个对象会为当前应用程序或整个系统接收所有鼠标事件。所谓鼠标捕获,是指对鼠标事件(onmousedown,onmouseup,onmousemove,onclick,ondblclick,onmouseover,onmouseout)进行捕捉,使在容器内的子对象的鼠标事件均…

  • es6 模板字符串_模板字符串如何实现

    es6 模板字符串_模板字符串如何实现es6的模板字符串个人觉得是很好用的,尤其简化了字符串拼接这块,下面说下它是如何使用的首先,模板字符串是增强版的字符串,使用反引号“来包括字符串,如果需要拼接上变量,那拼接的格式是使用${}包裹变量即可举个例子看下最基本的用法,可以看出来跟普通字符串拼接比较起来简洁容易了很多2:模板字符串的另一优点是,空格和缩进都会保留在输出中,之前的字符串换行的话需要拼接换行符,缩进需要使用缩…

  • java jersey使用总结_Java Jersey2使用总结

    java jersey使用总结_Java Jersey2使用总结前言在短信平台一期工作中,为便于移动平台的开发,使用了JavaJersey框架开发RESTFul风格的WebService接口。在使用的过程中发现了一些问题并积累了一些项目经验,做了一下总结,便于个人成长,同时也希望对有需要的同仁有好的借鉴和帮助。简介Jersey是JAX-RS(JSR311)开源参考实现用于构建RESTfulWebservice,它包含三个部分:核心服务器(CoreS…

  • 计算机中1kb表示的字节数是多少_在计算机中1KB是指几字节

    计算机中1kb表示的字节数是多少_在计算机中1KB是指几字节大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。1kb等于1024个字节。kB(Kilobyte),是一种资讯计量单位,是计算机数据存贮器存储单位字节的多倍形式。现今通常在标识内存等具有一般容量的储存媒介之储存容量时使用。根据国际单位制标准,1kB=1000B(字节,Byte)。根据按照IEC命名标准,用于二进制存储单位的标准命名是KiB,MiB等,1kiB=1024B。这是由…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号