re: 跳出多層循環的簡單方法(Java版) 銀河使者 2009-01-30 16:13
不可以的,我試了,編譯不過去。我用的是jdk6
re: JDBC查詢動態封裝 銀河使者 2009-01-29 19:31
封裝本是面象對象最值得稱道的地方,如果封裝得太多有時得不償失。個人認為在業務邏輯層,只要不直接涉及到SQL就可以,因為SQL本身是和數據庫相關的,而業務邏輯層應和數據庫不相關。但對于JDBC中的對象的使用上來說,一般也是和數據庫不相關的(至少對于象SQL Server、oracle、db2、mysql這樣的數據庫來說是這樣的)。
結論:數據訪問層直接和數據庫相關,可以涉及任何的SQL語句。業務邏輯層與數據庫無關,在該層直接訪問數據層,不能直接在業務邏輯層編寫SQL語句,但可以使用JDBC的相關對象。
re: JDBC查詢動態封裝 銀河使者 2009-01-29 19:26
@ cccp21
不討論PreparedStatement了,要想動態,一般也是采用你的方法,即動態生成帶SQL參數的SQL語句,以及通過循環調用setter方法來設置參數的值,這就是動態,所有的動態基本都是這么弄的。
我是說第二個問題,在查詢后,又使用Map和Vector再對數據進行封裝,是不是有些耗資源。要注意哦,如果是Web程序,可不是一個用戶或幾個用戶在訪問程序啊,要是門戶類型的系統,可能在一分鐘之內就會有數以萬計的用戶來訪問。這時就要建立多達數萬個Map和Vector,服務器會掛的。當然,如果用戶在可控范圍內,這么做是沒有問題的。但是可以封裝得更高級一些,如返回的這些數據直接可以被某些用于顯示的組件使用,如使用json格式的組件。這根據具體情況而定。
是的,使用Map和Vector可以從邏輯上將JDBC和應用進行分離。但個人認為要想分離,可以從數據層及應用邏輯層進行分離更好。也就是有數據層提供相應的訪問數據的方法,如獲得指定用戶的保存在數據庫中的密碼。而應用邏輯層一般不直接訪問數據庫,可以訪問數據層中的方法進行邏輯處理。
雖然將數據放在Map是Vector中是更抽象了,但JDBC本身就是抽象的,在業務邏輯層直接訪問ResultSet并沒有什么不妥,因為不管后臺用的是什么數據庫,從ResultSet中獲得數據的方法都是一樣的。如果非想要跨數據庫,不如直接用hibernate。
re: JDBC查詢動態封裝 銀河使者 2009-01-26 19:00
條件是動態的也可以用查詢參數,用java.sql.PreparedStatement就可以。樓主只是做了個封裝,不過個人認為ResultSet本身也可以根據列名來定位列,而再把每行放在一個Map中,再把結果集放在Vector中,感覺有些多此一舉。
re: 判斷一個類是另一個類的子類 銀河使者 2009-01-22 14:59
可以使用b instanceOf a
re: Hibernate的十大罪狀 銀河使者 2009-01-22 14:14
個人認為這種基于ORM的技術最好與語言和開發工具融合,也就是屬于語言或開發工具的一部分,無縫結合,這要比framework更容易使用,說實話,所謂framework,實際上就是一個大大的patch,正因為語言不支持,才會做成framework來彌補這個不足,就象AOP,如果語言支持,那誰還會再實現一套AOP framework?
re: Hibernate的十大罪狀 銀河使者 2009-01-22 09:05
hibernate從總體上說設計思想還是很不錯的,但高級的東西總是需要大量時間和精力去學習和研究。這也是hibernate的弊端。 這就象有一把絕世好劍,用好了,可以天下無敵,用不好可能會反傷了自己。
軟件的發展歷史也說明了這一點,想起當前使用面向過程的方式進行程序設計,雖然沒有現在面向對象的思想選進,但程序結構很簡單,實現也很容易,也沒這么多設計模式,說起來很省力。而現在的OOP,雖然看似很先進,但實際上大大增加了程序的復雜度,之所有現在OOP的設計思想使程序設計更簡單,是因為程序規模的增長已經遠遠超過了面向過程升級到OOP所增加的復雜度。
@Hadis
一般FilterDispatcher可設為"/*"以結果所有的請求,當然,也可以設為*.action,只截獲action請求,
不知你客戶端的jsp頁面是GBK,還是utf-8,就算你在自己的過濾器中設了GBK,在執行FilterDispathcer時仍然按著Struts 2的設置來處理,就是說,還是會設成utf-8。你可以在自己的過濾器中在設置完request的gbk編碼后,使用request.getParameter方法來自己讀一下請求參數的值,看看是不是亂碼!
@Hadis
是這樣的,過濾器是對Servlet的,而Struts 2是通過攔截器來處理action的,當客戶端發送請求時,首先這個請求會被struts 2的過濾器攔截(在web.xml文件中可以看到處理action的struts 2過濾器),并進行分析,如果是action,則進行Struts 2的處理流程,也就是調用相應的struts 2攔截器,最后會調用action類的execute方法。在這個過程中,和web.xml中配置的其他過濾器一點關系都沒有,因為在web.xml文件中配置的過濾器并不會過濾action,而處理action的是由struts2的攔截器完成的。
如果客戶端發送的是非action的請求,則struts2會將其交由Servlet引擎來處理,這時過濾器才有效。
如果非要在程序中設置request的編碼,可以在struts 2的攔截器中設置。
@Hadis
是這樣的,Struts 2默認采用了UTF-8編碼(可以在struts.properties或struts.xml文件中修改這一設置),而我用的是GBK,把你的程序都改成UTF-8試試。實在不行,把你做的例子發給我,我的mail是asklining@126.com,我看看。發過來時別忘了留言。
時間復雜度怎么可能是O(1)呢?至少得移動結點啊,把算法或設計思想貼出來看看
在本系列的后續文章還會講到使用service.xml文件來發布webservice,這種方式比較好,除此之外,還會講到會話在web service中的應用,以及如何跨服務共享會話(session),在c#、delphi中使用調用復雜的web service等。
@加加
是這樣的,axis2實際上就是一個Web目錄,在該目錄中可以發布jsp、servlet,而webservice是依賴servlet來實現的,因此,也可以發布web service,當然,可以將axis2改成其他的名子,如ws。如果想發布類,一般有兩種方法:
1. 按著本文所述,直接放在pojo目錄或其他的發布目錄中。
2. 將這些類放在axis2\WEB-INF\classes目錄中,然后使用service.xml文件進行發布。這塊在后面的文章將詳細講解
在axis2目錄有一些jar文件還需要帶的,否則使用axis2無法成功發布web service,當然,axis2目錄中的jar文件并不是都需要,根據使用的功能需要不同的jar文件,不過為了簡單,可以將所有的jar包都保留。不過這是在服務端,應該沒什么關系。
re: [算法]09考研數據結構試題解法 銀河使者 2009-01-18 10:39
是的,@crtylr的算法比較好,下面的具體的實現代碼,很簡單:
private static int findNode(Node headNode, int k)
{
Node p1 = headNode, p2 = headNode;
for(int i = 0; i < k && p2.nextNode != null; i++)
p2 = p2.nextNode;
if(p2.nextNode == null) return 0;
while(p2.nextNode != null)
{
p1 = p1.nextNode;
p2 = p2.nextNode;
}
System.out.println(p1.nextNode.data);
return 1;
}
to ZelluX
這個方法不錯,下面是具體的實現代碼:
private static int findNode(Node headNode, int k)
{
Node p1 = headNode, p2 = headNode;
for(int i = 0; i < k && p2.nextNode != null; i++)
p2 = p2.nextNode;
if(p2.nextNode == null) return 0;
while(p2.nextNode != null)
{
p1 = p1.nextNode;
p2 = p2.nextNode;
}
System.out.println(p1.nextNode.data);
return 1;
}
re: [算法]09考研數據結構試題解法 銀河使者 2009-01-17 20:53
這是一個算法,詳細解釋見我的blog:
http://www.tkk7.com/nokiaguy/archive/2009/01/17/251722.html
private static int findNode(Node headNode, int k)
{
Node p = headNode, p1 = headNode, p2 = null;
int count = 0; // 表示結點數
while (p.nextNode != null)
{
p = p.nextNode;
count++;
// 遇到k的整數位個結點,進行分塊
if (count % k == 0)
{
if (p2 != null)
p1 = p2;
p2 = p;
}
}
// k超過鏈表結點數,未找到,返回0
if (p2 == null)
{
return 0;
}
else
{
int mod = count % k;
int offset = mod + 1; // 任何情況下,最終結果都是p1指向的結點向后移動(mod + 1)個結點
for (int i = 0; i < offset; i++)
p1 = p1.nextNode;
System.out.println(p1.data);
return 1;
}
}
這系列文章就是幾年前寫的,做個總結,不過一直沒發出來,現在發出來,如果讀者已經覺得這些已經會了或已經過時了,可以略過此文,看我寫的《Struts 2系列文章》或其他的文章,當然,也可以什么都不看,打打醬油也可,哈哈!
也許新版本的jdk可以不使用\uxxxx格式,但并不是所有的開發人員都使用最新的jdk,還有就是雖然新版本的jdk可以讀取其他格式的屬性文件,但有些框架可能并沒有使用這些功能,因此,使用Properties.load方法讀取屬性文件只能用在完全由自己控制的情況下,如果處理屬性文件的功能是其他人做的,而且還不能修改代碼,那就得聽天由命了,完全取決于這個人是否使用了新功能來處理屬性文件。
re: Java正則表達式初學者指南 銀河使者 2009-01-14 13:54
沒錯,看任何文章或書,如果一點都不思考,基本上是看不明白的,除非這些已經明白了!!
re: 我無法解釋的問題,請您一并來解釋 銀河使者 2009-01-14 12:54
只1500次,不可能產生內存溢出異常,根據你的描述是拋出NullPointerException異常,這說明你引用了一個對象變量,但這個對象變量值為null,問題出在equals方法中,有可能出在下面的代碼中:
myPolSchema other = (myPolSchema) otherObject;
return GrpContNo.equals(other.getGrpContNo())
&& GrpPolNo.equals(other.getGrpPolNo());
上面的代碼有可能other.getGrpConNo方法返回一個null,順便問一下,GrpContNo字段在什么時候賦的值?
re: Struts2教程8:攔截器概述 銀河使者 2008-12-29 08:37
struts2和webwork的攔截器在實現原理上基本一樣,只是struts 2的攔截器是webwork攔截器的一個超集,也就是說,struts 2攔截器在webwork攔截器的基礎上又增加了很多攔截器。從struts 2包中的struts-default.xml文件中就可以看到這點。在該文件中攔截器的定義如下:
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
<interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
<interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
<interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
<interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
<interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
<interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
<interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
<interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
<interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
<interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
<interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
<interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
我們看到上面的攔截器有很多是webwork的(xwork)。
個人感覺如果只是創建com組件,并調用其中的方法或屬性并不十分復雜,可以使用Jni技術用c++或delphi實現一個(返正做這個dll很簡單,以前用delphi做過很多這種東西),并在java中提供接口。 不知道jacob有沒有其他的功能?
@幻想~@@~
openoffice有自己的jdk,可以研究一下,不錯,很好很強大。
@郁林
com組件需要一個id來引用,這個錯誤是com組件的id錯了,或根本沒有這個組件。
jacob還沒用過,沒使用過java調用com,一般調用com就使用delphi、c#或c++了。有空研究一下jacob。不過個人認為,com是windows特有的,如果想調用com,可以使用windows下的語言或工具,如delphi,c#都是很好的選擇。最喜歡delphi,不會出現這樣那樣的兼容問題。當然,用vb6也很好。調用com并不是java的長項。如果非要使用java,那就只好用象jacob一樣的庫了。
不過還是支持樓主的文章!!!
不是validation.xmL文件,是<ActionClassName>-validation.xml文件
to 董
是這樣的,如果使用Struts 2的<s:textfield>或其他的表單標簽,字段錯誤是可以自動顯示出的,并不需要編寫代碼或使用<s:fielderror/>標簽去顯示,當然,使用<s:fielderror/>標簽也可以顯示字段錯誤,但就重復了。
如果使用普通的html標簽,就需要使用<s:fielderror/>標簽顯示字段錯誤了。如果是動作錯誤或消息,就需要使用<actionerror/>或<actionmessage/>標簽顯示了。
你好,很高興認識你。如果你有聯系方式,可以在我的blog里私人留言。 I'm glad to see you.
to Lau Jeffrey
由于前5個字節,第5個字節將漢字截取一半,所以把這個漢字去了,返回“a加b"
如果想將截一半的漢字要保留,可以將
if (i % 2 == 1)
{
// 該UCS2字符是漢字時,去掉這個截一半的漢字
if (bytes[i - 1] != 0)
i = i - 1;
// 該UCS2字符是字母或數字,則保留該字符
else
i = i + 1;
}
{
// 該UCS2字符是漢字時,去掉這個截一半的漢字
if (bytes[i - 1] != 0)
i = i - 1;
// 該UCS2字符是字母或數字,則保留該字符
else
i = i + 1;
}
改成
if (i % 2 == 1)
{
i = i + 1;
}
只是解釋一下為什么最好用String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");,哈哈。
在MyEclipse中開發基于hibernate的程序時,自動生成的Session工廠就用了ThreadLocal,以保證每一個線程只有一個Session。
實際上,ThreadLocal的基本原理就是利用線程的id作為Map的key,將一個對象作為Map的value, 以保證一個線程只有一個key-value對。由于每一個線程有一個獨立的對象,而且每個線程的對象必須獨立,也就是說不能有其他的線程訪問當前線程的對象,這樣對于每個線程來說,是順序執行的,也就不可能發生象臟數據這樣的事情了。
re: Struts2教程10:國際化 銀河使者 2008-08-20 15:19
正打算往下寫呢,不過現在正在寫這方面的書,時間有點緊,所以最近沒更新blog。等寫完了,會繼續深入探討struts 2。
to bigheadbird
是這樣的,可能是我沒寫清楚。在struts 2中,如果在<package>標簽中加namespace,一般需要在<s:form>標簽中使用namespace指定命名空間,再用action屬性指定動作名,代碼如下:
<s:form action="abcd" namespace="xyz" >
... ...
</s:form>
上面的代碼所對應的struts.xml中定義如下:
<package name="mypackage" namespace="xyz" extends="struts-default">
<action name="abcd" class="..."/>
</package>
如果按著上面的寫法是沒有任何問題的,也是Struts 2建議的方式
但要知道,<s:form>實際上就是對應的html的<form>標簽,而action屬性其實就是<form>的屬性,因此,也可以直接將命名空間寫在action屬性值中,而不使用<s:form>的namespace屬性。如下面代碼所示:
<s:form action="mystruts/sum.action" >
<s:textfield name="operand1" label=" 操作數1"/>
<s:textfield name="operand2" label=" 操作數2" />
<s:submit value="代數和" />
</s:form>
這么做同樣可以成功提交給Action類,但這么做,Struts 2會在控制臺輸出一個類似于下面的警告:
警告: No configuration found for the specified action: 'xyz/parent.action' in namespace: ''. Form action defaulting to 'action' attribute's literal value.
說是未找到xyz/parent.action, 這也說明Struts 2在處理時是將namespace和action屬性分開的。但這個警告并不會影響程序的運行。就象我們在編寫java或其他語言的程序時,編譯器可能會出現一些警告信息,但仍然可以編譯通過,并成功運行。
但要注意,如果不使用namespace,只使用action來表示命名空間的話,后面必須加上“.action”后綴,如果Struts 2未找到這個action,是不會自動加上.action后綴的。
實際上,還可以直接使用<form>來處理
我在后面的程序中直接使用了第二種方式,其實讀者可以選擇自己想用的方式,但筆者建議使用Struts 2建議的第一種方式。
沒錯,用javascript也是一種方法。不過我的教程只在演示struts 2關于這方面的功能,并不是為了實現而實現。 用javascript適合于所有的語言、所有的web系統。
re: AJAX從服務端獲取數據的三種方法 銀河使者 2008-07-28 20:34
實現多submit的方法非常多,這只是其中之一,在struts1.2.9以后的struts1.x版本中提供了一個action來處理,原理是通過判斷某個請求參數是否為null來處理(這個請求參數就是某個submit的name屬性值)
result里面的屬性可以是任何值,不能是execute,還有其它幾個actionsupport定義的方法名,否則會拋出異常,
re: AJAX從服務端獲取數據的三種方法 銀河使者 2008-07-19 19:51
本文的只是代碼片段,為了演示這個功能,本文已經假設讀者對javascript比較熟悉,因此,并沒有列出所有的代碼。如果那么,會無法突出重點,讓想看這部分內容的讀者不容易找到了。在以后的文章,我會提供源代碼供讀者下載學習。謝謝關注本文。
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 19:13
我看到網上關于在servlet中向客戶端輸出中文字符時亂碼解決方案一般是通過如下的代碼解決:
response.setCharacterEncoding("utf-8");
或
response.setContentType("text/html;charset=utf-8");
但關鍵是web服務器轉換字節時是否讀取了這個設置的字符集編碼呢?如果未讀取,等于沒設。所以最通用的方法是采用如同的代碼解決向客戶端中文亂碼的問題:
String ss = "中華人民共和國";
String utf8 = new String(ss.getBytes("utf-8"), "iso-8859-1");
response.setCharacterEncoding("iso-8859-1");
response.getWriter().write(utf8);
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 18:42
如果直接用getBytes("unicode"),就直接把ucs2編碼得出來了。
如果用下面的代碼:
zg.getBytes("unicode");
由于zg是以iso-8859-1保存的,因此,按著字節輸出,就會有下面的結果:
0
e4
0
b8
0
ad
0
e5
0
9b
0
bd
這也說明iso-8859-1的編碼轉換成ucs2后,第一個字節補0
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 18:41
要注意的一點就是getBytes和String都具有編碼轉換功能。
getBytes是將ucs2轉換成其他的編碼,而String是將其他的編碼轉換成ucs2編碼
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 18:30
@ James
不錯,你的第一種方法是比我的通用,因為你的方法是通過String類進行編碼轉換的,而我的是通過web服務器所提供的setCharacterEncoding方法實現編碼轉換的。由于String類是jdk的標準類,所以這種轉換方式和web服務器無關,任何基于java的程序(包括桌面程序)都可以使用這種方式進行轉換。
而且將其以ISO-8859-1取出,實際上用iso-8859-1往外取字節,就相當于是不經過轉換,直接取出來了,如將“中國"的utf-8編碼“0xe4, 0xb8, 0xad,0xe5,0x9b, 0xbd”直接用iso-8859-1保存在String中(注意,不是將其轉換成ucs2,而是直接用utf-8共6個字節將其保存在String中),代碼如下:
byte[] utf8 = new byte[]{(byte)0xe4, (byte)0xb8, (byte)0xad,(byte) 0xe5, (byte)0x9b, (byte)0xbd};
String zg = new String(utf8, "iso-8859-1");
String sss = new String(zg.getBytes("iso-8859-1"), "utf-8"); // 不能用utf-8
String zg1 = new String(sss.getBytes("utf-8"), "utf-8");
System.out.println(sss);
System.out.println(zg1);
其中 String zg = new String(utf8, "iso-8859-1");的作用就是將“中國”的6個utf-8編碼直接保存在String中,在這種情況下,不能使用zg.getBytes("utf-8")獲得字節,因為getBytes方法功能是將String中的ucs2編碼(4個字節)轉換成utf-8編碼的6個字節,而現在String中是6個字節的utf-8,而不是4個字節的ucs2,如果這時再用utf-8的話,java就會將這6個字節的utf-8編碼當成了3個ucs2編碼(2個字節為一個ucs2編碼),所以就會出現亂碼了。
而用zg.getBytes("iso-8859-1")就是將這6個字節的utf-8編碼按原樣取出,然后用 new String(zg.getBytes("iso-8859-1"), "utf-8");將這6個字節按著utf-8格式轉換成了java內部使用的ucs2編碼。(實際上utf-8編碼并沒有真正轉化為ucs2,因為這樣太占資源了,在程序中還可能有很多英文字符,因此,utf-8就直接放到那了,反正將它轉換成ucs也很容易)。
而在sss中的編碼就已經是utf-8(ucs2)了,因此,必須使用下面的代碼獲得字節數組:
sss.getBytes("utf-8")
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 17:06
沒有辦法,由于做服務器的大多都是老外,它們永遠不會有編碼問題的,所以估計request.setCharacterEncoding方法就成了可選實現的功能的,但我想國產的web服務器應該都支持,如apusic 。
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 17:05
如果response.setCharacterEncoding不好使,可以試試response.setContentType("text/html;charset=utf-8");
如果都不好使,就想別的方法,方法還是有的呢,可以用%xxxx形式,或是看一下setCharacterEncoding是怎么弄的,自已處理一下。
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 16:59
@James
我的程序是在tomcat6調試通過的,你說的可能是tomcat5以前的版本,但那應該是這些版本的bug,從理論上,是必須支持這個功能的,否則web程序是無法在這些web服務器上運行的。但很遺憾,我沒有碰到過這些版本的tomcat。
至于web亂碼問題,我只是簡單提了一下,本文的目的并不是解決web亂碼問題。而是讓讀者了解java內部編碼的問題。如果了解了java編碼原理,你認為web亂碼問題,甚至其他的亂碼問題還能算是問題嗎?
你說的沒錯,用form提交是產生亂碼問題的一種原因,而用httpxmlrequest提交也會產生亂碼。這種情況下最好使用encodeURI或encodeURIComponent將中文編成%xxxx的形式,然后在服務端使用java.net.URLDecoder.decode方法進行解碼。
象在struts里的actionform,都可能會產生亂碼問題。
還有就是在http請求頭或響應頭中傳中文,也會出現亂碼問題。這些只要了解了java的編碼體系,都可以迎刃而解。
最后總結一下:
一般編碼傳送可以采用兩種方式:
1、直接編碼。就是采用utf-8、gbk等形式。這樣在服務端可以使用setCharacterEncoding指定相應的編碼。
2、使用url形式的編碼。如%xxxx
如果使用<form>的話,會根據當前瀏覽器的編碼確定發送的中文編碼。
如果用javascript,會以utf-8編碼發送。
re: Java編碼問題解決方案大揭密 銀河使者 2008-07-19 16:46
@James
不好意思,我的程序都是在tomcat6里調試通過的,再說這些都是servlet規范規定的,所有的web服務器必須遵循。如果某個web服務器不遵循,那么web程序也就無法在其上正常運行了。
web亂碼的問題非常多