在基于JAVA的编程中,经常会碰到汉字的处里及显示的问题,比如一大堆乱码或问号。这是因为JAVA中默认的编码方式是UNICODE,而中国人通常使用的文件和DB都是基于GB2312或者BIG5等编码,故会出现此问题。本文抽取了UFO中的演示实例来介绍如何解决中文乱码问题, UFO是www.gm365.com发布的一个web server软件(以建设网站的稳定性和高负载能力,快速的响应速度和低CPU消耗的功能而开发)。1、解决jsp中文乱码问题
    在jsp中,当使用out.print(request.getParameter("parameter-name"))输出表单数据时,如果表单数据为中文字符时,则输出的内容是乱码。引起中文乱码的原因是,在默认情况下,提取表单数据使用的编码格式为UTF-8.为了解决中文乱码问题,首先要使用 ISO-8859-1 编码格式将表单数据存储到字节数组中,然后再使用借助 gb2312的编码格式将字节数组转换为字符串。完整的处理表单的程序代码如下:例如:我们要将用户提交的表单数据输入到页面,直接用如下方法将会在parameter-name为中文字符时出现乱码
<%
String pName =request.getParameter("parameter-name");
out.println(pName);
%>
需要对其做如下改动可解决此类中文字符乱码问题:
<%
String pName =request.getParameter("parameter-name");
byte[] bytesStr=pName.getBytes("ISO-8859-1");
out.println(new String(bytesStr,"gb2312"));
%>2、如何处理servlet中的中文字符乱码问题(以jsp文件调用servlet为例来演示如何处理中文字符)ioFileServlet.jsp (此jsp文件用来写入文件、提交给servlet文件ioFileServlet来处理)<%@ page contentType="text/html;charset=GB2312" %>
<script language="javascript">
 function on_submit()
 {//验证数据的合法性
  if (form1.file_content.value == "")
    {
     alert("文件内容不能为空,请输入文件内容!");
     form1.file_content.focus();
     return false;
    }
 }
</script>
<HTML>
<head>
<title>提交文件内容</title>
</head>
<BODY>
<div align="center">
  <center>
<table border="1">
<tr><td colspan="2" align="center">用servlet处理输入的文件内容</td></tr>
<tr>
<tr><td>
<form name="form1" action="servlet/readdata/ioFileServlet" method="post" onsubmit="return on_submit()">
  请输入文件内容:
</td><td>
<textarea rows="7" name="file_content" cols="52"></textarea>
  </td></tr>
<tr><td colspan="2" align="center"><input type="submit" value="提交"></td></tr>
</form>
</table>
  </center>
</div>
</html>servlet文件ioFileServlet的源代码:
ioFileServlet.javapackage readdata;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ioFileServlet extends HttpServlet
{  
 public String codeToString(String str)
  {//处理中文字符串的函数
    String s=str;
    try
      {
      byte tempB[]=s.getBytes("ISO-8859-1");
      s=new String(tempB);
      return s;
  }
  catch(Exception e)
    {
    return s;
    }
  }
  public void init(ServletConfig config) throws ServletException
    {
      super.init(config);
    }
  public  void  doPost(HttpServletRequest request,HttpServletResponse response) 
                        throws ServletException,IOException
    {
       //设置mime
       response.setContentType("text/html;charset=GB2312");
       PrintWriter out=response.getWriter();
       out.println("<HTML><head><title>接收新用户注册</title></head><BODY>");
       //把提交的文件内容写入文件
       int RowSize=30;//文件每行的字符数
       String tempString1=null;
       String tempString2=null;
       tempString1=codeToString(request.getParameter("file_content"));
       if(tempString1!=null)
       { 
         File tempFile1=new File("d:/fileContent.txt");
         FileWriter outfile1=new FileWriter(tempFile1,true);
         BufferedWriter outbuffer1=new BufferedWriter(outfile1);
         int writeStringLength=tempString1.length();
         for(int i=0;i<writeStringLength/RowSize+1;i++)
         { 
           if((i+1)*20<writeStringLength)
           {
             tempString2=tempString1.substring(i*RowSize,(i+1)*RowSize);
           }
           else
           {
             tempString2=tempString1.substring(i*RowSize,writeStringLength);
           } 
           outbuffer1.write(tempString2);
           outbuffer1.newLine();
         }
         outbuffer1.flush();
         outbuffer1.close();
         outfile1.close();
        }
       out.println("写入的文件内容是:<br>");
       //从文件中读取内容
       File f=new File("d:/fileContent.txt"); 
       if(f.exists())
       {  
         FileReader fileReader1=new FileReader(f);
         BufferedReader buffer1=new BufferedReader(fileReader1);
         byte bufferArray[]=new byte[90];
         String tempString=null;
         while((tempString=buffer1.readLine())!=null)
         {
           out.println(tempString+"<br>");
         }
         buffer1.close();
         fileReader1.close();
       }
       else
       {
         out.println("故事中暂时没有内容。");
       }
       out.println("</body> </html>");
    } 
}servlet功能用来接受ioFileServlet.jsp页面写入的内容、将其存入d盘根目录中的fileContent.txt中(如果没有就新建),最后将写入到fileContent.txt文件的所有内容显示出来。去掉servle处理中文字符串的函数、即不对servlet中的中文字符串进行处理,写入文件的内容将显示乱码。

解决方案 »

  1.   

    让html和servlet的编码一致也许可以
    乱码的现象的原因很多,也有可能是容器问题
      

  2.   

    编码的问题很简单,只是网上有太多关于编码的错误理解,误导了纯洁的童鞋。
    要解决编码问题首先要弄明白一下几个问题。
    1. getBytes有什么作用?
    2. new String 有什么作用?
    3. request.setCharacterEncoding有什么作用?
    4. response.setCharacterEncoding有什么作用?
    5. charset是干什么的?pageEncoding是什么?
    6. 什么是url编码?
    7. 为什么浏览器的地址栏会出现%开头的类似字符串?
    8. 浏览器如何发送http请求内容?
    9. servlet容器是如何解析浏览器请求内容的?
    10. get和post的请求内容servlet容器的解析方式一样吗?
    这些问题很多,一时也说不完,大家可以先想想,我稍后会做出解答。
      

  3.   

    getBytes()就是编码,所谓编码,就是将字符串转换为字节,对于字符串“中国”来说,以utf-8编码生成的字节和用gbk编码生成的字节是不同的。
    "中国".getBytes("utf-8"),就是将“中国”以utf-8进行编码。
    "中国".getBytes(), 就是将“中国”以平台默认的编码方式进行编码,对于中文windows操作系统,就是gbk反过来 new String()就是解码,解码就是将某种编码的字节序列转换成字符串。
    new String()是以平台默认的编码方式进行解码,new String("utf-8")是以utf-8进行解码。
      

  4.   

    request.setCharacterEncoding设置请求头charset的值。
    response.setCharacterEncoding设置响应头charset的值。
    那么什么是charset?有什么作用?
    我们知道不管是http请求还是响应,实际上都是浏览器和服务器之间的一种通信。
    怎么通信?熟悉计算机网络的童鞋知道,归根结底,浏览器和服务器只能相互发送“010100110”这样的字节,
    它们当然不能发送字符串!!!
    那么它们是如何解析这些字节的呢?
    这就是http协议规定的内容,请求头从哪里开始,到哪里结束,请求体从哪里开始,到哪里结束,等等
    我们知道字节按照不同的编码方式可以解码成不同的字符串。charset指定了浏览器和服务器如何解码。
    请求头的charset表示请求内容的编码方式,它告诉了servlet容器,浏览器是以什么样的编码方式编码请求内容。
    响应头的charset表示响应内容的编码方式,它告诉了浏览器,servlet容器是以什么样的方式编码响应内容。