1. 程式人生 > >解決web伺服器各種應用的亂碼問題(轉)

解決web伺服器各種應用的亂碼問題(轉)

亂碼問題:

(1)伺服器端: 
修改httpd.conf (在Redhat中放置的位置為/etc/httpd/conf/) 
查詢: 
AddDefaultCharset ISO-8859-1 
改成: 
#AddDefaultCharset ISO-8859-1 


AddDefaultCharset off 
]

這種方式關掉了伺服器的預設語言的傳送,這樣僅憑html檔案頭中設定的語言來決定網頁語言。 

很多文章都說通過修改為 AddDefaultCharset GB2312 把預設語言改成GB2312來解決中文亂碼,確實GB2312內碼的網頁可以正常顯示了,但這並非萬全之策。因為當你的網頁內碼不是GB2312,就算你在網頁用下面的meta指定了正確的語言,如ISO8859-1,也不會解碼為ISO8859-1,因為Apache已經先你一步將GB2312指定為網頁的語言了,


(2)養成良好的習慣,在每個網頁的<head>;</head>;的最前面加入這行: 

    
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">; 


  一般的中文版網頁編輯工具(例如FrontPage、Dreamweaver等)都會自動加上這行。 

3、如何解決中文檔名無法訪問 

 
 在ie中選擇 工具 ->; internet選項 ->; 高階 ->; 取消“總是以UTF-8傳送URL”。 




UTF-8網頁空白,在網頁中加上metadata標識後,還需要手動調整編碼為 utf-8 才能正常顯示

如果使用的是Mozilla、Mozilla Firefox、Sarafi等其他目前流行的瀏覽器,通常就不會有這樣的問題。

在網頁的meta中指定用UTF-8:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />; 


在<head>;</head>;之前,把"Content-Type"放在最前面,便可以解決這樣的問題了。 

原因:

IE 解析網頁編碼時是 HTML 內的標識優先的,然後是 HTTP header ;而mozilla 系列的瀏覽器剛剛好相反。

一般情況在,很多人是把<title>;</title>;排在最前面,並且在title中就出現了UTF-8中文,這樣,IE在解析時,就先遇到UTF-8,不往下解析了,因此必須把如果把meta放在UTF-8出現之前,這樣IE才能判斷這個網頁是以UTF-8編碼的。 


總之:
無論是 PHP、JSP、ASP 或其他動態網頁的指令碼語言,如果需要作編碼設定,最好放在最前面。

使用php,也可以定義php的預設語言. 


php.ini中: 

default_charset = "gb2312" 


釋掉此行,做了以上修改,一樣是為了讓瀏覽器根據網頁頭中的charset來自動選擇語言,這樣就可以在同臺伺服器上提供多種語言的網頁服務。


java中文亂碼的解決 


 
 
在基於JAVA的程式設計中,經常會碰到漢字的處裡及顯示的問題,比如一大堆亂碼或問號。
這是因為JAVA中預設的編碼方式是UNICODE,而中國人通常使用的檔案和DB都是基於GB2312或者BIG5等編碼,故會出現此問題。

1、在網頁中輸出中文。

JAVA在網路傳輸中使用的編碼是"ISO-8859-1",故在輸出時需要進行轉化,如:
String  str="中文";
str=new  String(str.getBytes("GB2312"),"8859_1");
但如果在編譯程式時,使用的編碼是“GB2312”,且在中文平臺上執行此程式,不會出現此問題,一定要注意。

2、從引數中讀取中文

這正好與在網頁中輸出相反如:
str=new  String(str.getBytes("8859_1"),"GB2312");

3、操作DB中的中文問題

一個較簡單的方法是:在“控制面扳”中,把“區域”設定為“英語(美國)”。如果還會出現亂碼,還可進行如下設定:
取中文時:str=new  String(str.getBytes("GB2312"));
向DB中輸入中文:str=new  String(str.getBytes("ISO-8859-1"));

4、在JSP中的中文解決:

在“控制面扳”中,把“區域”設定為“英語(美國)”.
在JSP頁面中加入:
如果還不行正常顯示,則還要進行下面的轉換:
如:name=new  String(name.getBytes("ISO-8859-1"),"GBK");
就不會出現中文問題了。

CGI的?不知道對不?

找到CGI.pm,開啟它,找到$self->;charset('ISO-8859-1');將它改為$self->;charset('GB2312');


 wingger 回覆於:2004-10-10 11:03:56

UP

 haohaoo 回覆於:2004-10-11 11:59:47

MM施主,俺崇拜你了

 wingger 回覆於:2004-10-12 11:50:30

補充:
如果使用php,也可以定義php的預設語言. 

php.ini中: 

;default_charset = "gb2312" 

注意這裡是註釋掉此行,做了以上修改,目的是為讓瀏覽器根據網頁頭中的charset來自動選擇語言,這樣就可以在同臺伺服器上提供多種語言的網頁服務。

 wingger 回覆於:2004-10-12 12:31:33

java中文亂碼的解決 


 
 
在基於JAVA的程式設計中,經常會碰到漢字的處裡及顯示的問題,比如一大堆亂碼或問號。
這是因為JAVA中預設的編碼方式是UNICODE,而中國人通常使用的檔案和DB都是基於GB2312或者BIG5等編碼,故會出現此問題。

1、在網頁中輸出中文。

JAVA在網路傳輸中使用的編碼是"ISO-8859-1",故在輸出時需要進行轉化,如:
String  str="中文";
str=new  String(str.getBytes("GB2312"),"8859_1");
但如果在編譯程式時,使用的編碼是“GB2312”,且在中文平臺上執行此程式,不會出現此問題,一定要注意。

2、從引數中讀取中文

這正好與在網頁中輸出相反如:
str=new  String(str.getBytes("8859_1"),"GB2312");

3、操作DB中的中文問題

一個較簡單的方法是:在“控制面扳”中,把“區域”設定為“英語(美國)”。如果還會出現亂碼,還可進行如下設定:
取中文時:str=new  String(str.getBytes("GB2312"));
向DB中輸入中文:str=new  String(str.getBytes("ISO-8859-1"));

4、在JSP中的中文解決:

在“控制面扳”中,把“區域”設定為“英語(美國)”.
在JSP頁面中加入:
如果還不行正常顯示,則還要進行下面的轉換:
如:name=new  String(name.getBytes("ISO-8859-1"),"GBK");
就不會出現中文問題了。

 level 回覆於:2004-10-12 12:39:34

:em02:

 wingger 回覆於:2004-10-12 12:49:43

CGI的應該是這個:

找到CGI.pm,找到$self->;charset('ISO-8859-1');將它改為$self->;charset('GB2312');

或按以上同樣處理,應該可以

 wingger 回覆於:2004-10-31 14:59:03

徹底解決Tomcat 5.0.19中文亂碼

  一、Include的頁面亂碼

  現象:include進來的頁面出現亂碼,其它頁面正常。

  原因:Tomcat在預設情況下使用ISO-8859-1編碼,但是在include時有時Tomcat不能正確根據外層.jsp檔案的編碼解析include進來的檔案,造成include進來的檔案中的中文亂碼。

  解決:這兒可以有很多解決辦法,但是對於我們的中文環境,從根本上的解決辦法是將Tomcat 5.0.19的核心預設編碼從ISO-8859-1修改為GBK 。

  
  二、提交的資料亂碼

  現象:通過表單提交的資料出現亂碼。

  原因:原因未明。可能是Tomcat在接收到請求後,並沒有能夠根據request中的資訊提前正確的編碼方式。

  解決:可以新增一個設定字符集的Filter。

package filters;


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 {
 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 {

 // Conditionally select and set the character encoding to be used
 if (ignore || (request.getCharacterEncoding() == null)) {
  String encoding = selectEncoding(request);
  if (encoding != null)
   request.setCharacterEncoding(encoding);
 }

 // Pass control on to the next filter
 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);
}

  

配置web.xml

<filter>

 <filter-name>Set Character Encoding</filter-name>
 <filter-class>filters.SetCharacterEncodingFilter</filter-class>
 <init-param>
  <param-name>encoding</param-name>
  <param-value>GBK</param-value>
 </init-param>
</filter>

<filter-mapping>
 <filter-name>Set Character Encoding</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>



 wingger 回覆於:2004-10-31 15:05:12

沒試過不知道行不行

java Servlet 中文亂碼問題

import java.io.*;

import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class GetFormData extends HttpServlet
{
    public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
    {
        String paramValues;
        paramValues=request.getParameter("UserName";
        response.setContentType("text/html;charset=gb2312";
        PrintWriter out=response.getWriter();
        out.println("<html>;<title>;test</title>;<body>;";
        out.println("以下是收到的資料<br>;";
        out.println("UserName="+paramValues);
        out.println("<br>;接收結束";
        out.println("</body>;";
    }
    public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
    {
        doGet(request,response);
    }

}


只需要把 

paramValues=request.getParameterValues("UserName"改成下面的就可以了

paramValues=request.getParameter("UserName";


當然這句是必須的 response.setContentType("text/html;charset=gb2312"


 在jsdk2.1 tomcat及Domino5.8上的Servlet引擎執行通過了

 wingger 回覆於:2004-10-31 15:09:55

Weblogic Server中如何解決中文顯示亂碼問題 
《世界計算機》IT.ICXO.COM ( 日期:2004-09-29 16:07) 


--------------------------------------------------------------------------------
 
 
由於作業系統、瀏覽器、資料庫、JVM採用的字符集都不一樣,基於Weblogic Server開發的應用經常出現中文顯示亂碼問題,其實在Weblogic Server上執行的WEB應用有很多與字符集有關的設定,下面做一個總結,為了正確處理中文,最好把這些設定都設上。


1. 在JSP檔案頭加入
<%@ page contentType=text/html; charset=GBK %>; 
指定該JSP採用的字符集。



2.在Weblogic.xml檔案的中加入:

引用:encoding
GBK



指定JSP檔案中採用的字符集,在JSP檔案中的<%@ page contentType=text/html; charset=GBK %>;會覆蓋該設定



3.在Weblogic.xml檔案的中加入

compilerSupportsEncoding

true


如果為TRUE,指定在編譯JSP檔案時,採用在JSP檔案中定義的
<%@ page contentType=text/html; charset=GBK %>;或中定義的encoding引數中定義的字符集進行編碼,如果為FALSE,則採用JVM中預設指定的字符集進行編碼。



4. Weblogic Server需要把HTTP request(GET 和POST)中的資料從它的原始編碼轉化為Unicode,以便Java servlet API進行處理,為了做這種轉換,Weblogic Server需要知道HPPT request中的資料的編碼方式。這可以通過在Weblogic.xml的中設定.
〈INPUT-charset>;

/
GBK




5.從ORACLE資料庫中檢索出來的中文顯示不正確時,在這種情況下,如果資料庫使用的是中文字符集,並使用的是Type 2 JDBC Driver時,可加入Weblogic.codeset=GBK的屬性來解決這個問題。程式碼如下:

java.util.Properties props = new java.util.Properties();

props.put(Weblogic.codeset, GBK);
props.put(user, scott);
props.put(password, tiger);
String connectUrl = jdbc:Weblogic:oracle;
Driver myDriver = (Driver)
Class.forName(Weblogic.jdbc.oci.Driver).newInstance();
Connection conn = 
myDriver.connect(connectUrl, props);



6. 如果是採用WTC呼叫Tuxedo中的服務,在JSP頁面中無法正確顯示中文,必須使安裝Tuxedo的伺服器上的NLS_LANG環境變數與資料庫中的字符集的設定一樣。如後臺Oracle資料庫中的字符集設定為SIMPLIFIED CHINESE_CHINA.ZHS16GBK,那麼Tuxedo應用伺服器上的NLS_LANG環境變數應設定為:

export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK


 ccwwd 回覆於:2004-11-22 14:39:26

崇拜你呀!

 hitty 回覆於:2005-07-06 14:09:16

利害,加我吧....

PHP中文亂碼好像可以用:
ini_set('default_charset','gb2312');
來解決,要比改配置檔案要靈活一些....

 kot31 回覆於:2005-11-26 09:40:18

剛來這個論壇,看到了樓主的寶文,冒昧的問一下,文章中的 :wink: 是幹嘛用的? 

:wink:


 sipcom 回覆於:2006-02-15 16:45:32

我使用perl5.6,linux環境,用於連線oracle9i

根據上面的提示將CGI.pm中的改為GB2312後,查詢到的資料記錄顯示仍然為亂麻,中文無法顯示,這是why?

 樹和石頭 回覆於:2006-02-19 22:14:36

to sipcom:
在linux環境下不應該把字符集設為GB2312,而應該是iso-8859-1,詳細請參考以下內容:(資料來源:http://www.javadict.com/zxxx/2005711170800.htm)

Java/J2EE中文問題終極解決之道

Java中文問題一直困擾著很多初學者,如果瞭解了Java系統的中文問題原理,我們就可以對中文問題能夠採取根本的解決之道。

  最古老的解決方案是使用String的位元組碼轉換,這種方案問題是不方便,我們需要破壞物件封裝性,進行位元組碼轉換。

  還有一種方式是對J2EE容器進行編碼設定,如果J2EE應用系統脫離該容器,則會發生亂碼,而且指定容器配置不符合J2EE應用和容器分離的原則。

  在Java內部運算中,涉及到的所有字串都會被轉化為UTF-8編碼來進行運算。那麼,在被Java轉化之前,字串是什麼樣的字符集? Java總是根據作業系統的預設編碼字符集來決定字串的初始編碼,而且Java系統的輸入和輸出的都是採取作業系統的預設編碼。

  因此,如果能統一Java系統的輸入、輸出和作業系統3者的編碼字元集合,將能夠使Java系統正確處理和顯示漢字。這是處理Java系統漢字的一個原則,但是在實際專案中,能夠正確抓住和控制住Java系統的輸入和輸出部分是比較難的。J2EE中,由於涉及到外部瀏覽器和資料庫等,所以中文問題亂碼顯得非常突出。

  J2EE應用程式是執行在J2EE容器中。在這個系統中,輸入途徑有很多種:一種是通過頁面表單打包成請求(request)發往伺服器的;第二種是通過資料庫讀入;還有第3種輸入比較複雜,JSP在第一次執行時總是被編譯成Servlet,JSP中常常包含中文字元,那麼編譯使用javac時,Java將根據預設的作業系統編碼作為初始編碼。除非特別指定,如在Jbuilder/eclipse中可以指定預設的字符集。

  輸出途徑也有幾種:第一種是JSP頁面的輸出。由於JSP頁面已經被編譯成Servlet,那麼在輸出時,也將根據作業系統的預設編碼來選擇輸出編碼,除非指定輸出編碼方式;還有輸出途徑是資料庫,將字串輸出到資料庫。

  由此看來,一個J2EE系統的輸入輸出是非常複雜,而且是動態變化的,而Java是跨平臺執行的,在實際編譯和執行中,都可能涉及到不同的作業系統,如果任由Java自由根據作業系統來決定輸入輸出的編碼字符集,這將不可控制地出現亂碼。

  正是由於Java的跨平臺特性,使得字符集問題必須由具體系統來統一解決,所以在一個Java應用系統中,解決中文亂碼的根本辦法是明確指定整個應用系統統一字符集。

  指定統一字符集時,到底是指定ISO8859_1 、GBK還是UTF-8呢? 

  (1)如統一指定為ISO8859_1,因為目前大多數軟體都是西方人編制的,他們預設的字符集就是ISO8859_1,包括作業系統Linux和資料庫MySQL等。這樣,如果指定Jive統一編碼為ISO8859_1,那麼就有下面3個環節必須把握:

  開發和編譯程式碼時指定字符集為ISO8859_1。

  執行作業系統的預設編碼必須是ISO8859_1,如Linux。

  在JSP頭部宣告:<%@ page contentType="text/html;charset=ISO8859_1" %>。

  (2)如果統一指定為GBK中文字符集,上述3個環節同樣需要做到,不同的是隻能執行在預設編碼為GBK的作業系統,如中文Windows。

  統一編碼為ISO8859_1和GBK雖然帶來編制程式碼的方便,但是各自只能在相應的作業系統上執行。但是也破壞了Java跨平臺執行的優越性,只在一定範圍內行得通。例如,為了使得GBK編碼在linux上執行,設定Linux編碼為GBK。

  那麼有沒有一種除了應用系統以外不需要進行任何附加設定的中文編碼根本解決方案呢?

  將Java/J2EE系統的統一編碼定義為UTF-8。UTF-8編碼是一種相容所有語言的編碼方式,惟一比較麻煩的就是要找到應用系統的所有出入口,然後使用UTF-8去“結紮”它。

  一個J2EE應用系統需要做下列幾步工作:

開發和編譯程式碼時指定字符集為UTF-8。JBuilder和Eclipse都可以在專案屬性中設定。 
使用過濾器,如果所有請求都經過一個Servlet控制分配器,那麼使用Servlet的filter執行語句,將所有來自瀏覽器的請求(request)轉換為UTF-8,因為瀏覽器發過來的請求包根據瀏覽器所在的作業系統編碼,可能是各種形式編碼。關鍵一句:
request.setCharacterEncoding("UTF-8")。
網上有此filter的原始碼,Jdon框架原始碼中com.jdon.util.SetCharacterEncodingFilter
需要配置web.xml 啟用該Filter。 
在JSP頭部宣告:<%@ page contentType="text/html;charset= UTF-8" %>。 
在Jsp的html程式碼中,宣告UTF-8:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
設定資料庫連線方式是UTF-8。例如連線MYSQL時配置URL如下:
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
一般資料庫都可以通過管理設定設定UTF-8 
其他和外界互動時能夠設定編碼時就設定UTF-8,例如讀取檔案,操作XML等。 
     筆者以前在Jsp/Servlet時就採取這個原則,後來使用Struts、Tapestry、EJB、Hibernate、Jdon等框架時,從未被亂碼困擾過,可以說適合各種架構。希望本方案供更多初學者分享,減少Java/J2EE的第一個攔路虎,也避免因為採取一些臨時解決方案,導致中文問題一直出現在新的技術架構中。

 sipcom 回覆於:2006-02-20 12:01:38

原來是iso-8859-1,但無法顯示,在參考幾個文件後,改為GB2312,但還是無法顯示中文,我估計師apache的設定問題,但問題還沒解決

 yzmxf 回覆於:2006-02-20 20:50:37

太謝謝了 

今天就遇到了這個問題 明天去公司看看

不過應該可以解決  

謝謝法師斑竹 呵呵:em02::em02::em02:

 樹和石頭 回覆於:2006-02-25 10:29:07

那我就不知道了,我用的是weblogic伺服器,就是嚴格按照上面所說的步驟執行(少任何一個環節都不行)才能成功解決亂碼問題的。

無能為力了。同情。。。這個問題確實很頭疼,當時折騰了我一個多星期呢。
祝福你早日解決亂碼問題!

 softiger 回覆於:2006-02-27 09:53:26

也是web伺服器亂碼問題,百思不解,請高人指教,多謝啦1
Resin3.08在Linux As 3中一直執行正常,最近出現一個非常奇怪的問題,請各位朋友指點?

jsp從資料庫取得記錄後生成靜態檔案,如果Resin伺服器啟動時間不長,則生成檔案沒有亂碼出現,一切正常;Resin跑一段時間後,生成的檔案就出現了亂碼,Resin重新啟動後,重新生成檔案又是正常的。

可以確定,java編碼是正常的,為什麼會跑一段時間後才出現亂碼問題呢?檢視日誌也發現不了什麼異常。

 sipcom 回覆於:2006-03-01 15:49:50

我想把問題再清楚描述下:
我寫了cgi動態頁面,檔名test.pl
我用$perl test.pl
執行結果顯示查詢oracle資料庫中文顯示,但通過web方式http://xxxxxx/cgi-bin/test.pl下卻顯示資料庫中的中文記錄為???,靜態頁面中文顯示正常,why?

 sipcom 回覆於:2006-03-02 16:18:38

經過下午的摸索,問題終於解決了

在httpd.conf檔案中增加了一下1行
    AddCharset    GB2312       .zhs16gbk
(.zhs16gbk跟使用者環境下的nls_lang是一樣的值)