JSP中文乱码解决方案了解和TOMCAT中文乱码解决

java 中文乱码终极解决方案

首先,确保你的数据库是支持中文的。把数据库的编码方式设置能支持中文的,如GB2132,utf-8等,而且经过测试后确实能写入中文且正常显示。这样就就保证了数据库确实是支持中文的,且可以正常输入和保存中文。如果数据库本身都不支持中文字符,那不管你怎么写代码都是无济于事的,肯定会出现中文乱码。

其次,从输入源杜绝中文乱码出现的可能。只有从数据输入源杜绝了中文乱码出现的可能,才能保证输入到数据库中的是正确的字符,加上我们第一步的保障,那么就保证了从数据库中读取的数据的正确性,从而也就保证了程序从数据库中读取的数据不会出现中文乱码成为可能。解决方法:

解决方法一:从页面输入杜绝乱码出现的可能
1、在jsp输入页面中加入:
<%@pagecontentType="text/html;charset=数据库字符集"% >
2、在html标签的<head>的第一行加入
<meta http-equiv="Content-Type" content="text/html; charset=数据库字符集" />

解决方法二:使用javax.servlet.Filter
1、编写web.xml配置。在
这样就可以保证页面发送的数据的编码与数据库编码一致,这样从数据库中读取的数据就是你想要的正确字符了,你可放心的读取了

 

     < filter >
        
< filter-name > encoding </ filter-name >
        
< filter-class > com.morecans.test.EncodingFilter </ filter-class >
        
< init-param >
            
< param-name > charset </ param-name >
            
< param-value > utf-8 </ param-value >
        
</ init-param >
    
</ filter >
    
< filter-mapping >
        
< filter-name > encoding </ filter-name >
        
< url-pattern > /* </ url-pattern >
    
</ filter-mapping >

 


2、编写Filterservlet:com.morecans.test.EncodingFilter

 

package  com.morecans.test;

import  java.io.IOException;

import  javax.servlet.Filter;
import  javax.servlet.FilterChain;
import  javax.servlet.FilterConfig;
import  javax.servlet.ServletException;
import  javax.servlet.ServletRequest;
import  javax.servlet.ServletResponse;

public   class  EncodingFilter  implements  Filter  ... {
    
private FilterConfig config;

    
public void destroy() ...{
        System.out.println(
"*** destroy   EncodingFilter");

    }


    
public void doFilter(ServletRequest servletrequest,
            ServletResponse servletresponse, FilterChain filterchain)
            
throws IOException, ServletException ...{
        System.out.println(
"*** doFilter  EncodingFilter");
        String charset 
= this.config.getInitParameter("charset");
        servletrequest.setCharacterEncoding(charset);   //设
        servletresponse.setCharacterEncoding(charset);
        filterchain.doFilter(servletrequest, servletresponse);
    }


    
public void init(FilterConfig filterconfig) throws ServletException ...{
        
this.config = filterconfig;
        System.out.println(
"*** init  EncodingFilter");

    }


}

 

 

最后,在输出处避免乱码的出现。只有把输出控制好了,那么我们前面的工作就没有白费,前面的辛苦才会得到承认,才能得到收获。这一步,很简单,甚至都可以不要,因为我们前面的两步基本把这一步的工作也做了,我是说如果编码规范的话。然而,千里之堤,溃于蚁穴!行百里者半九十!希望前面的准备工作不会是徒劳,这是我们不原意看到的,所以在治理我还是建议不要因为这么一小步而错过了收获的季节。解决方法:

现在,你只需要在读取数据之前加上
request.setCharacterEncoding(数据库字符集);      
response.setCharacterEncoding(数据库字符集);  

而在jsp数据显示页面也像输出页面那样加上
<%@pagecontentType="text/html;charset=数据库字符集"% >                                
<meta http-equiv="Content-Type" content="text/html; charset=数据库字符集" />

整个过程,从源头到源尾,彻底的监视着数据的一举一动,时刻修正着数据的模样和流向,从而彻底消灭中文乱码这个恶魔的出现。

 

JSP中文乱码解决方案-Tomcat5.0版

首先,说说JSP/Servlet中的几个编码的作用。

JSP/Servlet中主要有以下几个地方可以设置编码,pageEncoding="UTF-8"contentType="text/html;charset=UTF-8"request.setCharacterEncoding("UTF-8")response.setCharacterEncoding("UTF-8"),其中前两个只能用于JSP中,而后两个可以用于JSPServlet中。

1pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码。

       众所周知,JSP在服务器上是要先被编译成Servlet的。pageEncoding="UTF-8"的作用就是告诉JSP编译器在将JSP文件编译成Servlet时使用的编码。通常,在JSP内部定义的字符串(直接在JSP中定义,而不是从浏览器提交的数据)出现乱码时,很多都是由于该参数设置错误引起的。例如,你的JSP文件是以GBK为编码保存的,而在JSP中却指定pageEncoding="UTF-8",就会引起JSP内部定义的字符串为乱码。

       另外,该参数还有一个功能,就是在JSP中不指定contentType参数,也不使用response.setCharacterEncoding方法时,指定对服务器响应进行重新编码的编码。

       2contentType="text/html;charset=UTF-8"的作用是指定对服务器响应进行重新编码的编码。

       在不使用response.setCharacterEncoding方法时,用该参数指定对服务器响应进行重新编码的编码。服务器在将数据发送到浏览器前,对数据进行重新编码时,使用的就是该编码。

       3request.setCharacterEncoding("UTF-8")的作用是设置对客户端请求进行重新编码的编码。

       该方法用来指定对浏览器发送来的数据进行重新编码(或者称为解码)时,使用的编码。

       4response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。

       服务器在将数据发送到浏览器前,对数据进行重新编码时,使用的就是该编码。

       其次,要说一说浏览器是怎么样对接收和发送的数据进行编码的

       response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。同时,浏览器也是根据这个参数来对其接收到的数据进行重新编码(或者称为解码)。所以在无论你在JSP中设置response.setCharacterEncoding("UTF-8")或者response.setCharacterEncoding("GBK"),浏览器均能正确显示中文(前提是你发送到浏览器的数据编码是正确的,比如正确设置了pageEncoding参数等)。读者可以做个实验,在JSP中设置response.setCharacterEncoding("UTF-8"),在IE中显示该页面时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是" UnicodeUTF-8",而在在JSP中设置response.setCharacterEncoding("GBK"),在IE中显示该页面时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是"简体中文(GB2312"

       浏览器在发送数据时,对URL和参数会进行URL编码,对参数中的中文,浏览器也是使用response.setCharacterEncoding参数来进行URL编码的。以百度和GOOGLE为例,如果你在百度中搜索"汉字",百度会将其编码为"%BA%BA%D7%D6"。而在GOOGLE中搜索"汉字"GOOGLE会将其编码为"%E6%B1%89%E5%AD%97",这是因为百度的response.setCharacterEncoding参数为GBK,而GOOGLE的的response.setCharacterEncoding参数为UTF-8

       浏览器在接收服务器数据和发送数据到服务器时所使用的编码是相同的,默认情况下均为JSP页面的response.setCharacterEncoding参数(或者contentTypepageEncoding参数),我们称其为浏览器编码。当然,在IE中可以修改浏览器编码(在IE的菜单中选择"查看(V)"à"编码(D)"中修改),但通常情况下,修改该参数会使原本正确的页面中出现乱码。一个有趣的例子是,在IE中浏览GOOGLE的主页时,将浏览器编码修改为"简体中文(GB2312",此时,页面上的中文会变成乱码,不理它,在文本框中输入"汉字",提交,GOOGLE会将其编码为"%BA%BA%D7%D6",可见,浏览器在对中文进行URL编码时,使用的就是浏览器编码。

       弄清了浏览器是在接收和发送数据时,是如何对数据进行编码的了,我们再来看看服务器是在接收和发送数据时,是如何对数据进行编码的。

       对于发送数据,服务器按照response.setCharacterEncoding—contentType—pageEncoding的优先顺序,对要发送的数据进行编码。

       对于接收数据,要分三种情况。一种是浏览器直接用URL提交的数据,另外两种是用表单的GETPOST方式提交的数据。

       因为各种WEB服务器对这三种方式的处理也不相同,所以我们以Tomcat5.0为例。

       无论使用那种方式提交,如果参数中包含中文,浏览器都会使用当前浏览器编码对其进行URL编码。

       对于表单中POST方式提交的数据,只要在接收数据的JSP中正确request.setCharacterEncoding参数,即将对客户端请求进行重新编码的编码设置成浏览器编码,就可以保证得到的参数编码正确。有写读者可能会问,那如何得到浏览器编码呢?上面我们提过了,在默认请情况下,浏览器编码就是你在响应该请求的JSP页面中response.setCharacterEncoding设置的值。所以对于POST表单提交的数据,在获得数据的JSP页面中request.setCharacterEncoding要和生成提交该表单的JSP页面的response.setCharacterEncoding设置成相同的值。

      对于URL提交的数据和表单中GET方式提交的数据,在接收数据的JSP中设置request.setCharacterEncoding参数是不行的,因为在Tomcat5.0中,默认情况下使用ISO-8859-1URL提交的数据和表单中GET方式提交的数据进行重新编码(解码),而不使用该参数对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码)。要解决该问题,应该在Tomcat的配置文件的Connector标签中设置useBodyEncodingForURI或者URIEncoding属性,其中useBodyEncodingForURI参数表示是否用request.setCharacterEncoding参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为falseTomcat4.0中该参数默认为true);URIEncoding参数指定对所有GET方式请求(包括URL提交的数据和表单中GET方式提交的数据)进行统一的重新编码(解码)的编码。URIEncodinguseBodyEncodingForURI区别是,URIEncoding是对所有GET方式的请求的数据进行统一的重新编码(解码),而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于URL提交的数据和表单中GET方式提交的数据,可以修改URIEncoding参数为浏览器编码或者修改useBodyEncodingForURItrue,并且在获得数据的JSP页面中request.setCharacterEncoding参数设置成浏览器编码。

      下面总结下,以Tomcat5.0WEB服务器时,如何防止中文乱码。

1、 对于同一个应用,最好统一编码,推荐为UTF-8,当然GBK也可以。

2、 正确设置JSPpageEncoding参数

3、 在所有的JSP/Servlet中设置contentType="text/html;charset=UTF-8"response.setCharacterEncoding("UTF-8"),从而间接实现对浏览器编码的设置。

4、 对于请求,可以使用过滤器或者在每个JSP/Servlet中设置request.setCharacterEncoding("UTF-8")。同时,要修改Tomcat的默认配置,推荐将useBodyEncodingForURI参数设置为true,也可以将URIEncoding参数设置为UTF-8(有可能影响其他应用,所以不推荐)。

 

tomcat乱码问题

實際運用 Tomcat 5.0.19,我們了解在不修改 Tomcat 原始碼的狀況下,使用者透過 Form submit 的資料將一律以 ISO8859-1 處理,程式設計師必須自行將字串將轉換為 Big5(繁體中文) or GB2312/GBK(簡體中文),我們在應用程式中,對所有的 request.getParameter("xx"); 作了 toBig5String() 的處理,理論上,所有的中文問題應該不會出現才對,結果,還是發現某些狀況下,中文還是變成亂碼!

經過分析整理,我們發現問題出在 QueryString 的解析,以前在 Tomcat 4.x 時代,無論 SUBMIT 時採用 GET or POST,Tomcat server 對 parameters 的處理都採用相同的編碼,但在 Tomcat 5.x 版,不知何故,卻將 QueryString 的解析獨立出來,目前確認,Form 的 Method 採用 GET 及直接將參數寫在 URL 上的中文,上傳到 Tomcat 時,無論如何轉碼,都會變成亂碼,那怕你事先作過 URLEncode 也一樣。

網站上,有人針對這個問題,建議將所有中文改採用 base64 編碼,到了 server 上,程式將自行土 base64 decode 回來,確保中文不會發生問題。這樣作法當然可以解決這個問題,但是所有網頁變成限定要採用 POST,且程式設計師要隨時分清楚,那個參數是採用 GET 上傳,那個參數是採用 POST 上傳,然後再針對不同的方式採用不同的解析,這樣的程式一點兒移植性都沒有,更別提跨平台、跨國際語言了。

研究 Tomcat 的文件及原始碼,我們找到了問題所在及解決的方法,只有按著以下的作法,才能使 Form submit 的資料完全按著 ISO8859-1 的編碼,當然,若是全照著 Tomcat 的文件說明去作,肯定還是不行,你還是得加上這個參數到 server.xml 中才行。

解決方案

請先研究 $TOMCAT_HOME/webapps/tomcat-docs/config/http.html 這個說明檔,擷錄重點如下:
URIEncoding:This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

useBodyEncodingForURI:This specifies if the encoding specified in contentType should be used for URI query parameters, instead of using the URIEncoding. This setting is present for compatibility with Tomcat 4.1.x, where the encoding specified in the contentType, or explicitely set using Request.setCharacterEncoding method was also used for the parameters from the URL. The default value is false.

上述二個 Tomcat 參數,是設定在 server.xml 中的 http <Connector /> 區塊,要解決 QueryString 中文變成亂碼的問題,你必須至少設定這二個參數其中之一。
URIEncoding 請設定為 URIEncoding="ISO-8859-1" 指定為 "ISO-8859-1" 編碼,讓 QueryString 的字元編碼與 post body 相同。
useBodyEncodingForURI 這是用來相容 Tomcat 4.x 版的,設定的值是 "true" or "false",意思是指 "要不要讓 QueryString 與 POST BODY 採用相同的字元編碼 ?",若是設成 true,那也可達到 "ISO-8859-1" 編碼的需求。
建議,採用 URIEncoding 的設定,畢竟 useBodyEncodingForURI 的作法是為了相容 Tomcat 4.X。不過若照原文的說明,理論上這二個參數都不設,Tomcat 也該採用 "ISO-8859-1" 的編碼,那為什麼還是會有問題呢 ? 我們由 Tomcat Source Code 來看就清楚了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 這一段碼是 Tomcat 用來解 QueryString 的程式,
// 在 org.apache.tomcat.util.http.Parameters 這個 class 裡。
private String urlDecode(ByteChunk bc, String enc)
  throws IOException {
  if( urlDec==null ) {
     urlDec=new UDecoder(); 
  }
  urlDec.convert(bc);
  String result = null;
  if (enc != null) {
    bc.setEncoding(enc);
    result = bc.toString();
  } 
  else {
    CharChunk cc = tmpNameC;
    cc.allocate(bc.getLength(), -1);
    // Default encoding: fast conversion
    byte[] bbuf = bc.getBuffer();
    char[] cbuf = cc.getBuffer();
    int start = bc.getStart();
    for (int i = 0; i < bc.getLength(); i++) {
      cbuf[i] = (char) (bbuf[i + start] & 0xff);
    }
    cc.setChars(cbuf, 0, bc.getLength());
    result = cc.toString();
    cc.recycle();
  }
  return result;
}


請特別注意紅色區塊,當 Tomcat 發現 QueryString 並沒有設定 encode 時,並非像文件中所說預設採用 ISO-8859-1 的編碼,而是用一段 fast conversion 來處理,才會造成中文問題,所以,還是必須在 Server.xml 中,加上 URLEncoding 的參數設定才行哦。

Connector 的設定範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Connector
debug="0"
acceptCount="100"
connectionTimeout="20000"
disableUploadTimeout="true"
port="80"
redirectPort="8443"
enableLookups="false"
minSpareThreads="25"
maxSpareThreads="75"
maxThreads="150"
maxPostSize="0"
URIEncoding="ISO-8859-1"
>
</Connector>



一般說來,我們在使用 Tomcat 4 透過 GET or POST 的方式傳參數時,通常都是使用 Filter 的方式來解決中文傳參數的問題。
但是到了 Tomcat 5.0.19 之後,解決中文傳遞參數時,就必須考慮是使用 GET or POST,兩種解決的方式不一樣。

如果是使用 GET 的方式傳遞時,就如同 精靈 兄 的文章所述,或者使用

1
String name = new String((request.getParameter("name")).getBytes("ISO-8859-1"),"Big5");



;若是使用 POST 的方式時,就延用傳統一般解決中文的方式

1
request.setCharacterEncoding("Big5");



不過當初我最後的做法是使用 Filter 的方式
Filter 的做法就是:先判斷是使用那種傳遞方式( GET or POST),假若是用 GET 的方式就採用第一種 code;若使用POST 方式,就採用第二種 code

1
URIEncoding="MS950"


測試結果在 windows 上是正常的

 

 

tomcat6 中文乱码

服务器是tomcat,操作系统是xp,采用的是MVC架构,模式是采用Facade模式,总是出现乱码,通过简单的设置页面字符集,总算可以正确显示中文,可是没想到表单里提交的数据里的中文还是有乱码,我狂晕,没想到JSP里的乱码问题比ASP里严重多了,自己也解决了好多天,同事也帮忙解决,也参考了网上众多网友的文章和意见,总算是搞定。但是好记性不如烂笔杆,所以特意记下,以防止自己遗忘,同时也给那些遇到同样问题的人提供一个好的参考途径:

        以下内容参考了网上的方法
(一)    JSP设计页面上是中文,但运行时看到的是乱码:
解决的办法就是在JSP页面的编码的地方<%@ page language="java" contentType="text/html;charset=GBK" %>,因为Jsp转成Java文件时的编码问题,默认的话有的服务器是ISO-8859-1,如果一个JSP中直接输入了中文,Jsp把它当作ISO8859-1来处理是肯定有问题的,这一点,我们可以通过查看Jasper所生成的Java中间文件来确认
 
(二)    当用Request对象获取客户提交的汉字代码的时候,会出现乱码,比如表单里:
解决的办法是:要配置一个filter,也就是一个Servelet的过滤器,代码如下:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
 
public class SetCharacterEncodingFilter implements Filter {
    public void destroy() 
     {
    }
 
    public void doFilter(ServletRequest request, ServletResponse response,
                                  FilterChain chain)throws IOException, ServletException 
     {
    request.setCharacterEncoding("GBK");
    // 传递控制到下一个过滤器
    chain.doFilter(request, response);
    }
 
    public void init(FilterConfig filterConfig) throws ServletException 
     {
    }
}
配置web.xml
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>com.SetCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果你的还是出现这种情况的话你就往下看看是不是你出现了第四中情况,你的Form提交的数据是不是用get提交的,一般来说用post提交的话是没有问题的,如果是的话,你就看看第四中解决的办法。
还有就是对含有汉字字符的信息进行处理,处理的代码是:
package dbJavaBean;
public class CodingConvert
{   
public CodingConvert()
{
          // process
}
 
public String toGb(String uniStr)
{
     String gbStr = "";
     if(uniStr == null)
       {
            uniStr = "";
     }
     try
       {
   byte[] tempByte = uniStr.getBytes("ISO8859_1");
   gbStr = new String(tempByte,"GB2312");
     }
       catch(Exception ex)
      {
              // exception process
     }
     return gbStr;
 }
   
 public String toUni(String gbStr)
 {
     String uniStr = "";
     if(gbStr == null)
       {
            gbStr = "";
     }
     try
       {
   byte[] tempByte = gbStr.getBytes("GB2312");
   uniStr = new String(tempByte,"ISO8859_1");
     }
       catch(Exception ex)
      {
     }
     return uniStr;
}
}
你也可以在直接的转换,首先你将获取的字符串用ISO-8859-1进行编码,然后将这个编码存放到一个字节数组中,然后将这个数组转化成字符串对象就可以了,例如:
String str=request.getParameter(“girl”);
Byte B[]=str.getBytes(“ISO-8859-1”);
Str=new String(B);
通过上述转换的话,提交的任何信息都能正确的显示。
 
(三)    在Formget请求在服务端用request. getParameter(“name”)时返回的是乱码;按tomcat的做法设置Filter也没有用或者用request.setCharacterEncoding("GBK");也不管用问题是出在处理参数传递的方法上:如果在servlet中用doGet(HttpServletRequest request, HttpServletResponse response)方法进行处理的话前面即使是写了:
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
也是不起作用的,返回的中文还是乱码!!!如果把这个函数改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。
同样,在用两个JSP页面处理表单输入之所以能显示中文是因为用的是post方法传递的,改成get方法依旧不行。
由此可见在servlet中用doGet()方法或是在JSP中用get方法进行处理要注意。这毕竟涉及到要通过浏览器传递参数信息,很有可能引起常用字符集的冲突或是不匹配。
解决的办法是:
1) 打开tomcat的server.xml文件,找到区块,加入如下一行: 
URIEncoding=”GBK” 
完整的应如下: 
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
 enableLookups="false" redirectPort="8443" acceptCount="100" debug="0"
 connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"/>
 
2)重启tomcat,一切OK。
需要加入的原因大家可以去研究 $TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的这个文件就可以知道原因了。需要注意的是:这个地方如果你要是用UTF-8的时候在传递的过程中在Tomcat中也是要出现乱码的情况,如果不行的话就换别的字符集。
 
(四)    JSP页面上有中文,按钮上面也有中文,但是通过服务器查看页面的时候出现乱码:
     解决的办法是:首先在JSP文件中不应该直接包含本地化的消息文本,而是应该通过<bean:message>标签从Resource Bundle中获得文本。应该把你的中文文本放到Application.properties文件中,这个文件放在WEB-INF/classes/*下,例如我在页面里有姓名,年龄两个label,我首先就是要建一个Application.properties,里面的内容应该是name=”姓名” age=”年龄”,然后我把这个文件放到WEB-INF/classes/properties/下,接下来根据Application.properties文件,对他进行编码转化,创建一个中文资源文件,假定名字是Application_cn.properties。在JDK中提供了native2ascii命令,他能够实现字符编码的转换。在DOS环境中找到你放置Application.properties的这个文件的目录,在DOS环境中执行一下命令,将生成按GBK编码的中文资源文件Application_cn.properties:native2ascii ?encoding gbk Application.properties Application_cn.properties执行以上命令以后将生成如下内容的Application_cn.properties文件:name=/u59d3/u540d age=/u5e74/u9f84,在Struts-config.xml中配置:<message-resources parameter="properties.Application_cn"/>。到这一步,基本上完成了一大半,接着你就要在JSP页面上写<%@ page language="java" contentType="text/html;charset=GBK" %>,到名字的那个label是要写<bean:message key=”name”>,这样的化在页面上出现的时候就会出现中文的姓名,年龄这个也是一样,按钮上汉字的处理也是同样的。
 
(五)    写入到数据库是乱码:
解决的方法:要配置一个filter,也就是一个Servelet的过滤器,代码如同第二种时候一样。
如果你是通过JDBC直接链接数据库的时候,配置的代码如下:jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK,这样保证到数据库中的代码是不是乱码。
如果你是通过数据源链接的化你不能按照这样的写法了,首先你就要写在配置文件中,在tomcat 5.0.19中配置数据源的地方是在
C:/Tomcat 5.0/conf/Catalina/localhost这个下面,我建立的工程是workshop,放置的目录是webapp下面,workshop.xml的配置文件如下:
<!-- insert this Context element into server.xml -->
<Context path="/workshop" docBase="workshop" debug="0"
           reloadable="true" >
  <Resource name="jdbc/WorkshopDB"
               auth="Container"
               type="javax.sql.DataSource" />
  <ResourceParams name="jdbc/WorkshopDB">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>
    <parameter>
      <name>maxActive</name>
      <value>100</value>
    </parameter>
    <parameter>
      <name>maxIdle</name>
      <value>30</value>
    </parameter>
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>
      <parameter>
     <name>username</name>
     <value>root</value>
    </parameter>
    <parameter>
     <name>password</name>
     <value></value>
    </parameter>
    <!-- Class name for mm.mysql JDBC driver -->
    <parameter>
       <name>driverClassName</name>
       <value>com.mysql.jdbc.Driver</value>
     </parameter>
    <parameter>
      <name>url</name>
        <value>
           <![CDATA[jdbc:mysql://localhost:3306/workshopdb?useUnicode=true &amp;characterEncoding=GBK]]>
        </value>
    </parameter>
  </ResourceParams>
</Context>
粗体的地方要特别的注意,和JDBC直接链接的时候是有区别的,如果你是配置正确的化,当你输入中文的时候到数据库中就是中文了,有一点要注意的是你在显示数据的页面也是要用<%@ page language="java" contentType="text/html;charset=GBK" %>这行代码的。需要注意的是有的前台的人员在写代码的是后用Dreamver写的,写了一个Form的时候把他改成了一个jsp,这样有一个地方要注意了,那就是在Dreamver中Action的提交方式是request的,你需要把他该过来,因为在jsp的提交的过程中紧紧就是POST和GET两种方式,但是这两种方式提交的代码在编码方面还是有很大不同的,这个在后面的地方进行说明。3
以上就是我在开发系统中解决中文的问题,不知道能不能解决大家的问题,时间匆忙,没有及时完善,文笔也不是很好,有些地方估计是词不达意。大家可以给我意见,希望能共同进步。
 
其它上按以上的方法就可以解决的。
第(二)种方法里,这个过滤器比较简单,如果字符集不同的话,那就要手动修改这个过滤器,下面介绍一个功能强的过滤器:

package com.manage.filter;
import javax.servlet.*;
import java.io.IOException;

public class SetCharacterEncodingFilter implements Filter {
protected String encoding = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
if (ignore || (request.getCharacterEncoding() == null)) {
String encoding = selectEncoding(request);
if (encoding != null)
request.setCharacterEncoding(encoding);
}
chain.doFilter(request, response);
}

public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
String value = filterConfig.getInitParameter("ignore");
if (value == null)
this.ignore = true;
else if (value.equalsIgnoreCase("true"))
this.ignore = true;
else if (value.equalsIgnoreCase("yes"))
this.ignore = true;
else
this.ignore = false;
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}
}//EOC
/**在web.xml里这样设置
  <filter>
  <filter-name>Set Character Encoding</filter-name>
  <filter-class>
   com.manage.filter.SetCharacterEncodingFilter
  </filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
   <param-name>ignore</param-name>
   <param-value>true</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>Set Character Encoding</filter-name>
  <servlet-name>action</servlet-name>
 </filter-mapping>
*/
 
针对第(二)种方法,还有一个很简单的方法,就是在每个页面里都加上以下代码:<%request.setCharacterEncoding("gb2312");%>
<%response.setCharacterEncoding("gb2312");%>
这样听说行,不过我试了没有效果

 

js解决中文乱码问题----总结 

 

//解决乱码问题方法:1.页面发出的数据做一次encodeURI(在js文件),服务器使用new String(name.getBytes("ISO-8859-1"),"UTF-8");
//方法2.页面端发出的数据做两次encodeURI,服务器使用URLDecoder.decode(name,"UTF-8");

javascript里边这样使用:var url = encodeURI("AJAXServlet?name="+$("#userName").val());

在java里边: name = new String(name.getBytes("ISO-8859-1"),"UTF-8");
           //或者     name = URLDecoder.decode(name,"UTF-8");

 

Ajax中文乱码与跨域访问

AJAX中文乱码问题的解决方法有两种:

(1)页面端数据作一次encodeURI,服务器端稍作改变即可

面面端verify.js脚本:

function verify()
{
    //1.接收html数据
    //解决中文乱码问题的方法:页面端发出的数据作一次encodeURI,服务器端使用new String(old.getBytes("iso8859-1"),"UTF-8");     
     var url ="AJAXServer?name="+encodeURI($("#userName").val());//页面端发出的数据作一次encodeURI
        url = convertURL(url);
        $.get(url,function (data)
        {
            $("#result").html(data);

        });
        //2.对数据进行发送
        //3.回调函数
    }
    function convertURL(url)
    {
        var timetamp = (new Date()).valueOf();
        if(url.indexOf("?")>=0)
        {
            url=url+"&t"+timetamp;
        }
        else
        {
            url=url+"?t"+timetamp;
        }
        return url;
}

 

服务器端的程序稍作修改即可,对字符串用指定方式编码:

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;

/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2009-1-5
 * Time: 21:26:55
 * To change this template use File | Settings | File Templates.
 */
public class AJAXServer extends HttpServlet
{
    protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        doGet(httpServletRequest, httpServletResponse);
    }

    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        //写校验代码


                try{

            httpServletResponse.setContentType("text/html;charset=utf-8");     
            PrintWriter out = httpServletResponse.getWriter();
            Integer inte = (Integer)httpServletRequest.getSession().getAttribute("total");
            int temp = 0;                   
            //1.取参数信息
            if (inte == null)
            {
                temp = 1;
            }
            else
            {
                temp = inte.intValue() + 1;
            }
            httpServletRequest.getSession().setAttribute("total",temp);


            String old = httpServletRequest.getParameter("name");
            String name = new String(old.getBytes("iso8859-1"),"UTF-8");//服务器稍作修改即可,用指定方式编码
            //2.检查参数是否有问题
            if(old == null || old.length() == 0){
                out.println("用户名不能为空");
            } else{

                //3.校验操作
                if(name.equals("wangxingkui")){
                    //4。和传统应用不同之处。这一步需要将用户感兴趣的数据返回给页面段,而不是将一个新的页面发送给用户
                    //写法没有变化,本质发生了改变
                    out.println("用户名[" + name + "]已经存在,请使用其他用户名, " + temp);
                } else{
                    out.println("用户名[" + name + "]尚未存在,可以使用该用户名注册, " + temp);
                }
            }
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

 

(2)解决中文乱码问题:页面端发出的数据作两次encodeURI,服务器作一URLDecoder.decode(old,UTF-8)

页面端verify.js的脚本:

function verify()
{
    //1.接收html数据    
    //解决中文乱码问题的方法:页面端发出的数据作两次的encodeURI,服务器端作一次URLDecoder.decode(old,"UTF-8");   
    var url ="AJAXServer?name="+encodeURI(encodeURI($("#userName").val()));//页面端的数据作两次encodeURI
        url = convertURL(url);

        $.get(url,function (data)
        {
            $("#result").html(data);

        });
        //2.对数据进行发送
        //3.回调函数
    }
    function convertURL(url)
    {
        var timetamp = (new Date()).valueOf();
        if(url.indexOf("?")>=0)
        {
            url=url+"&t"+timetamp;
        }
        else
        {
            url=url+"?t"+timetamp;
        }
        return url;
}

 

服务器端的数据作一次URLDecoder.decode(old,UTF-8);的解码工作,服务器端只作一次的解码工作就可以了,因为在浏览器的内部还会做一次解码,所以服务器只作一次就可以了

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;

/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2009-1-5
 * Time: 21:26:55
 * To change this template use File | Settings | File Templates.
 */
public class AJAXServer extends HttpServlet
{
    protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        doGet(httpServletRequest, httpServletResponse);
    }

    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        //写校验代码


                try{
            httpServletResponse.setContentType("text/html;charset=utf-8");     
            PrintWriter out = httpServletResponse.getWriter();
            Integer inte = (Integer)httpServletRequest.getSession().getAttribute("total");
            int temp = 0;                   
            //1.取参数信息
            if (inte == null)
            {
                temp = 1;
            }
            else
            {
                temp = inte.intValue() + 1;
            }
            httpServletRequest.getSession().setAttribute("total",temp);


            String old = httpServletRequest.getParameter("name");
           String name = URLDecoder.decode(old,"UTF-8");//这是服务器端做的一次解码工作

            //2.检查参数是否有问题
            if(old == null || old.length() == 0){
                out.println("用户名不能为空");
            } else{
                //3.校验操作
//                String name = old;
                if(name.equals("wangxingkui")){
                    //4。和传统应用不同之处。这一步需要将用户感兴趣的数据返回给页面段,而不是将一个新的页面发送给用户
                    //写法没有变化,本质发生了改变
                    out.println("用户名[" + name + "]已经存在,请使用其他用户名, " + temp);
                } else{
                    out.println("用户名[" + name + "]尚未存在,可以使用该用户名注册, " + temp);
                }
            }
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

 

js函数 escape,encodeURI,encodeURIComponent比较 

 

js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decodeURIComponent

escape() 方法:

采用ISO Latin字符集对指定的字符串进行编码。所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是%20。

不会被此方法编码的字符: @ * / +

encodeURI() 方法:

把URI字符串采用UTF-8编码格式转化成escape格式的字符串。

不会被此方法编码的字符:! @ # $& * ( ) = : / ; ? + '

encodeURIComponent() 方法:

把URI字符串采用UTF-8编码格式转化成escape格式的字符串。与encodeURI()相比,这个方法将对更多的字符进行编码,比如 / 等字符。所以如果字符串里面包含了URI的几个部分的话,不能用这个方法来进行编码,否则 / 字符被编码之后URL将显示错误。
不会被此方法编码的字符:! * ( ) '
因此,对于中文字符串来说,如果不希望把字符串编码格式转化成UTF-8格式的(比如原页面和目标页面的charset是一致的时候),只需要使用escape。如果你的页面是GB2312或者其他的编码,而接受参数的页面是UTF-8编码的,就要采用encodeURI或者encodeURIComponent。
另外,encodeURI/encodeURIComponent是在javascript1.5之后引进的,escape则在javascript1.0版本就有。

 

1、   传递参数时需要使用encodeURIComponent,这样组合的url才不会被#等特殊字符截断。                           

例如:<script language="javascript">document.write('<a href="http://passport.baidu.com/?logout&aid=7&u='+encodeURIComponent("http://cang.baidu.com/bruce42")+'">退出</a>');</script>

2、   进行url跳转时可以整体使用encodeURI

例如:Location.href=encodeURI("http://cang.baidu.com/do/s?word=百度&ct=21");

3、   js使用数据时可以使用escape

例如:搜藏中history纪录。

4、   escape对0-255以外的unicode值进行编码时输出%u****格式,其它情况下escape,encodeURI,encodeURIComponent编码结果相同。


最多使用的应为encodeURIComponent,它是将中文、韩文等特殊字符转换成utf-8格式的url编码,所以如果给后台传递参数需要使用encodeURIComponent时需要后台解码对utf-8支持(form中的编码方式和当前页面编码方式相同)

escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z

encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z

encodeURIComponent不编码字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z

 

传递key的时候,为了防止中文乱码,使用encodeURIComponent编码:
<script>
     function searchSubmit(){
                     reg = /[/S]+/;
                     obj=$("search_word");
                    if(!obj.value.match(reg)){
                         alert("请输入搜索的关键词!");
                        return;
                     }
                     location.href="/place/search?id=" + getUrlParam("id") + "&word=" + encodeURIComponent(obj.value);
       }
</script>
但在后台java代码直接request.getParameter("word")就已经乱码了,还没调用URLDecoder.decode。
找资料发现调用request.getParameter的时候java会自动对word进行一次解码,所以就乱码。既然java会自动对word进行一次解码,那我们在前台进行2次编码,然后后台URLDecoder.decode(request.getParameter("word"),"utf-8")就可以解决乱码的问题。
前台代码:
<script>
                function searchSubmit(){
                     reg = /[/S]+/;
                     obj=$("search_word");
                    if(!obj.value.match(reg)){
                         alert("请输入搜索的关键词!");
                        return;
                     }
                     location.href="/place/search?id=" + getUrlParam("id") + "&word=" + encodeURIComponent(encodeURIComponent(obj.value));
                 }
             </script>


 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值