2008年7月29日

          struts-config.xml中 action 的attribute屬性與name屬性

          1、在一般情況下,actionForm是被存儲在一定的scope中(request或session,通過action的scope屬性來配置),當(dāng)我們在配置時,指定name而不指定attribute,那么指定的name值就作為actionForm存儲在scope中的key值,我們可以在action中通過httpServletRequest.getAttribute("指定的name屬性值")來獲得這個actionForm;     當(dāng)我們既配置了name又配置了attribute,那么actionForm存儲在scope中的key值就采用attribute屬性指定的值了,這時要通過httpServletRequest.getAttribute("指定的attribute屬性值")來獲得actionForm,此時通過httpServletRequest.getAttribute("指定的name屬性值")是不能獲得actionForm的。  
             
              所以,是否配置attribute屬性就決定了actionForm存儲在scope中的key值是采用name,還是采用attribute

           2、 在《Programming Jakarta Struts》這本書中的第四章“Configuring the Struts Application”中這樣一段說明來分別闡述這兩
          個屬性:(102頁)
          ++++++++
          atribute:
          ++++++++
          The name of the request or session scope attribute under which the form bean for this action can be accessed.
          A value is only allowed here if there is a form bean specified in the name attribute. This attribute is
          optional and has no default value.

          ++++++++
          name:
          ++++++++
          The name of the form bean, if any, that is associated with this action. This value must be the name attribute
          from one of the form-bean elements defined earlier. This attribute is optional and has no default value.

          最初看這些真的還是不好區(qū)分這兩者。不過在仔細看過struts的源代碼以后,豁然開朗。。。

          下面主要對attribute進行解釋,應(yīng)為沒有人會對name屬性不了解的(呵呵。。。)


          解釋:在struts實例化actionform的時候,有兩種情況:如果已經(jīng)存在,那么從內(nèi)存中取回;如果第一次實例化,那么創(chuàng)建,并放入內(nèi)存。
          這樣就有一個問題了,struts是根據(jù)什么來取回并創(chuàng)建actionform的呢,答案就是attribute的值。讓我們進入struts的源代碼:

          /**
          *創(chuàng)建或者取回formbean方法
          *該方法在:org.apache.struts.util.RequestUtils中
          */
          public static Actionform createActionform(
          HttpServletRequest request,
          ActionMapping mapping,
          ModuleConfig moduleConfig,
          ActionServlet servlet) {
          。。。。
          。。。
          // Is there a form bean associated with this mapping?
          //得到action mapping中attribute的值
          String attribute = mapping.getAttribute();
          。。。。
          。。。。
          Actionform instance = null;
          HttpSession session = null;
          //yes!!就在這里了,把創(chuàng)建以后的actionform放在request或者session里,看到放入的名字了么,就是mapping.getAttribute();
          if ("request".equals(mapping.getScope())) {
          instance = (Actionform) request.getAttribute(attribute);
          } else {
          session = request.getSession();
          instance = (Actionform) session.getAttribute(attribute);
          }
          。。。
          。。。


          }


          下面又有一個問題浮出水面:如果我沒有在action mapping中指定attribute呢,那struts 是如何解決的?
          答案很簡單,如果單從結(jié)果上看,此時struts使用的name的值,為什么呢,看struts源代碼:

          /**
          * The request-scope or session-scope attribute name under which our
          * form bean is accessed, if it is different from the form bean's
          * specified <code>name</code>.
          *該代碼在:org.apache.struts.config.ActionConfig中
          */
          protected String attribute = null;

          public String getAttribute() {
          //yes!!!!就在這里,看到了吧,如果你沒有設(shè)定attribute,那么struts 會把name的值拿過來用。呵呵。。。
          if (this.attribute == null) {
          return (this.name);
          } else {
          return (this.attribute);
          }
          }

          public void setAttribute(String attribute) {
          if (configured) {
          throw new IllegalStateException("Configuration is frozen");
          }
          this.attribute = attribute;
          }

          posted @ 2008-09-20 13:37 chenkai 閱讀(702) | 評論 (1)編輯 收藏

          Request的getParameter和getAttribute方法的區(qū)別

          當(dāng)兩個Web組件之間為轉(zhuǎn)發(fā)關(guān)系時,轉(zhuǎn)發(fā)源會將要共享 request范圍內(nèi)的數(shù)據(jù)先用setAttribute將數(shù)據(jù)放入到HttpServletRequest對象中,然后轉(zhuǎn)發(fā)目標(biāo)通過 getAttribute方法來取得要共享的數(shù)據(jù)。而MVC中用的就是Web組件之間的轉(zhuǎn)發(fā)??!真是笨,怎么當(dāng)時沒有想到呢?

                下面整理一下getParameter和getAttribute的區(qū)別和各自的使用范圍。

                (1)HttpServletRequest類有setAttribute()方法,而沒有setParameter()方法

                (2)當(dāng)兩個Web組件之間為鏈接關(guān)系時,被鏈接的組件通過getParameter()方法來獲得請求參數(shù),例如假定welcome.jsp和authenticate.jsp之間為鏈接關(guān)系,welcome.jsp中有以下代碼:

                <a  href="authenticate.jsp?username=wolf">authenticate.jsp  </a>

                或者:

                <form  name="form1"  method="post"  action="authenticate.jsp">
                    請輸入用戶姓名:<input  type="text"  name="username">
                    <input  type="submit"  name="Submit"  value="提交">
                </form>

                 在authenticate.jsp中通過request.getParameter("username")方法來獲得請求參數(shù)username:

                 <%  String  username=request.getParameter("username");  %>

                 (3)當(dāng)兩個Web組件之間為轉(zhuǎn)發(fā)關(guān)系時,轉(zhuǎn)發(fā)目標(biāo)組件通過getAttribute()方法來和轉(zhuǎn)發(fā)源組件共享request范圍內(nèi)的數(shù)據(jù)。

                  假定  authenticate.jsp和hello.jsp之間為轉(zhuǎn)發(fā)關(guān)系。authenticate.jsp希望向hello.jsp傳遞當(dāng)前的用戶名字,  如何傳遞這一數(shù)據(jù)呢?先在authenticate.jsp中調(diào)用setAttribute()方法:

                  <%
                  String  username=request.getParameter("username");
                  request.setAttribute("username",username);
                  %>

                  <jsp:forward  page="hello.jsp"  />

                  在hello.jsp中通過getAttribute()方法獲得用戶名字:

                  <%  String  username=(String)request.getAttribute("username");  %>
                  Hello:  <%=username  %>

                  從更深的層次考慮,request.getParameter()方法傳遞的數(shù)據(jù),會從Web客戶端傳到Web服務(wù)器端,代表HTTP請求數(shù)據(jù)。request.getParameter()方法返回String類型的數(shù)據(jù)。

                  request.setAttribute()和getAttribute()方法傳遞的數(shù)據(jù)只會存在于Web容器內(nèi)部,在具有轉(zhuǎn)發(fā)關(guān)系的Web組件之間共享。這兩個方法能夠設(shè)置Object類型的共享數(shù)據(jù)。

                  request.getParameter()取得是通過容器的實現(xiàn)來取得通過類似post,get等方式傳入的數(shù)據(jù)。

                  request.setAttribute()和getAttribute()只是在web容器內(nèi)部流轉(zhuǎn),僅僅是請求處理階段。

                  getAttribute是返回對象,getParameter返回字符串

                  總的來說:request.getAttribute()方法返回request范圍內(nèi)存在的對象,而request.getParameter()方法是獲取http提交過來的數(shù)據(jù)。

          posted @ 2008-09-20 09:57 chenkai 閱讀(2793) | 評論 (0)編輯 收藏

          用javascript實現(xiàn)table的排序

          <%@page
          language="java"
          contentType="text/html;charset=GBK"
          %>

          <html>
          <head>
              <title>MyHtml.html</title>
              <meta http-equiv="content-type" content="text/html; charset=gbk">
             
              <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

             <script  language="javascript">

           

          function   JM_PowerList(colNum)  
            {  
            headEventObject=event.srcElement;//取得引發(fā)事件的對象  
            while(headEventObject.tagName!="TR")   //不是tr行,則從底下的td冒泡上來尋找到相應(yīng)行  
            {  
            headEventObject=headEventObject.parentElement;  
            }  
             
            for   (i=0;i<headEventObject.children.length;i++)  
            {   alert(headEventObject.children[i].tagName);
            if   (headEventObject.children[i]!=event.srcElement)//找到事件發(fā)生的td單元格  
            {  
            headEventObject.children[i].className='listTableHead';//把點擊的列的className屬性設(shè)為listTableHead  
            }  
            }  
             
            var   tableRows=0;  
            trObject=clearStart.children[0].children;   //取得表格中行對象,   原來這里叫DataTable,   可能是你寫錯了吧??  
            for   (i=0;i<trObject.length;i++)  
            {  
            Object=clearStart.children[0].children[i];//取得每行的對象  
            tableRows=(trObject[i].id=='ignore')?tableRows:tableRows+1;//如果不是忽略行,則行數(shù)加一  
            }  
             
            var   trinnerHTML=new   Array(tableRows);    
            var   tdinnerHTML=new   Array(tableRows);  
            var   tdNumber=new   Array(tableRows)  
            var   i0=0  
            var   i1=0  
            for   (i=0;i<trObject.length;i++)  
            {  
            if   (trObject[i].id!='ignore')  
            {  
            trinnerHTML[i0]=trObject[i].innerHTML;//把行放在數(shù)組里  
            tdinnerHTML[i0]=trObject[i].children[colNum].innerHTML;//把要排序的行中td的內(nèi)容放數(shù)組里  
            tdNumber[i0]=i;//行號  
            i0++;//加一,下個循環(huán)用  
            }  
            }  
            sourceHTML=clearStart.children[0].outerHTML;//取得表格中所有tr的html代碼  
             
            //對所有td中的字符串進行排序,   算不算冒泡排序???  
            for   (bi=0;bi<tableRows;bi++)  
            {  
            for   (i=0;i<tableRows;i++)  
            {  
            if(tdinnerHTML[i]>tdinnerHTML[i+1])  
            {  
            t_s=tdNumber[i+1];  
            t_b=tdNumber[i];  
            tdNumber[i+1]=t_b;  
            tdNumber[i]=t_s;  
            temp_small=tdinnerHTML[i+1];  
            temp_big=tdinnerHTML[i];  
            tdinnerHTML[i+1]=temp_big;  
            tdinnerHTML[i]=temp_small;  
            }  
            }  
            }  
             
             
             
            var   showshow='';  
            var   numshow='';  
            for   (i=0;i<tableRows;i++)  
            {  
            showshow=showshow+tdinnerHTML[i]+' ';//把排序好的td的內(nèi)容存在showshow字串里  
            numshow=numshow+tdNumber[i]+'|';             //把排序好的相應(yīng)的行號也存在numshow中  
            }  
             
            sourceHTML_head=sourceHTML.split("<TBODY>");//從<TBODY>截斷,我試了,前頭串為空  
             
            numshow=numshow.split("|");  
            var   trRebuildHTML='';  
            if   (event.srcElement.className=='listHeadClicked')  
            {//已點擊的列,   則逆排  
            for   (i=0;i<tableRows;i++)  
            {  
            trRebuildHTML=trRebuildHTML+trObject[numshow[tableRows-1-i]].outerHTML;//取出排序好的tr的內(nèi)容連接起來  
             
            }  
            event.srcElement.className='listHeadClicked0';  
            }  
            else  
            {//默認順排,新點擊順排  
            for   (i=0;i<tableRows;i++)  
            {  
            trRebuildHTML=trRebuildHTML+trObject[numshow[i]].outerHTML;  
            }  
            event.srcElement.className='listHeadClicked';  
            }  
            //取得排序后的tr集合結(jié)果字符串  
            var   DataRebuildTable='';  
            //把舊的表格頭和新的tr排序好的元素連接起來,   (修改了一下)  
            DataRebuildTable   =   "<table   border=1 width=100%  cellpadding=1 cellspacing=1 id='clearStart'><TBODY>"
                +   trObject[0].outerHTML   +   trRebuildHTML   +   "</TBODY>"   +      "</table>";  
            clearStart.outerHTML=DataRebuildTable;//表格用新串重新寫一次  
             
            }  

          </script>

            </head>
          <table border=1 id="clearStart">
           <tr bgcolor=cccccc id='ignore'>
            <td onclick="JM_PowerList(0)">列一
            </td>
            <td onclick="JM_PowerList(1)">
             列二
            </td>
            <td onclick="JM_PowerList(2)">
             列二
            </td>
           </tr>
            <tr>
            <td>
             周
            </td>
            <td>
             公務(wù)員
            </td>
            <td>
             22
            </td>
           </tr>
           <tr>
            <td>
             張三
            </td>
            <td>
             研究員
            </td>
            <td>
             65
            </td>
           </tr>
           <tr>
            <td>
             李思
            </td>
            <td>
             科學(xué)家
            </td>
            <td>
             24
            </td>
           </tr>
           <tr>
            <td>
            王武
            </td>
            <td>
             社會學(xué)家
            </td>
            <td>
             38
            </td>
           </tr>
          </table>
          </body></html>

           

          posted @ 2008-08-09 11:40 chenkai 閱讀(396) | 評論 (0)編輯 收藏

          Java 編程技術(shù)中漢字問題的分析及解決

          在基于 Java 語言的編程中,我們經(jīng)常碰到漢字的處理及顯示的問題。一大堆看不懂的亂碼肯定不是我們愿意看到的顯示效果,怎樣才能夠讓那些漢字正確顯示呢?Java語言默認的編碼方式是UNICODE,而我們中國人通常使用的文件和數(shù)據(jù)庫都是基于GB2312或者BIG5等方式編碼的,怎樣才能夠恰當(dāng)?shù)剡x擇漢字編碼方式并正確地處理漢字的編碼呢?本文將從漢字編碼的常識入手,結(jié)合Java編程實例,分析以上兩個問題并提出解決它們的方案。

          現(xiàn)在 Java 編程語言已經(jīng)廣泛應(yīng)用于互聯(lián)網(wǎng)世界,早在 Sun 公司開發(fā) Java 語言的時候,就已經(jīng)考慮到對非英文字符的支持了。Sun 公司公布的 Java 運行環(huán)境(JRE)本身就分英文版和國際版,但只有國際版才支持非英文字符。不過在 Java 編程語言的應(yīng)用中,對中文字符的支持并非如同 Java Soft 的標(biāo)準(zhǔn)規(guī)范中所宣稱的那樣完美,因為中文字符集不只一個,而且不同的操作系統(tǒng)對中文字符的支持也不盡相同,所以會有許多和漢字編碼處理有關(guān)的問題在我們進行應(yīng)用開發(fā)中困擾著我們。有很多關(guān)于這些問題的解答,但都比較瑣碎,并不能夠滿足大家迫切解決問題的愿望,關(guān)于 Java 中文問題的系統(tǒng)研究并不多,本文從漢字編碼常識出發(fā),分析 Java 中文問題,希望對大家解決這個問題有所幫助。

          漢字編碼的常識

          我們知道,英文字符一般是以一個字節(jié)來表示的,最常用的編碼方法是 ASCII 。但一個字節(jié)最多只能區(qū)分256個字符,而漢字成千上萬,所以現(xiàn)在都以雙字節(jié)來表示漢字,為了能夠與英文字符分開,每個字節(jié)的最高位一定為1,這樣雙字節(jié)最多可以表示64K格字符。我們經(jīng)常碰到的編碼方式有 GB2312、BIG5、UNICODE 等。關(guān)于具體編碼方式的詳細資料,有興趣的讀者可以查閱相關(guān)資料。我膚淺談一下和我們關(guān)系密切的 GB2312 和 UNICODE。GB2312 碼,中華人民共和國國家標(biāo)準(zhǔn)漢字信息交換用編碼,是一個由中華人民共和國國家標(biāo)準(zhǔn)總局發(fā)布的關(guān)于簡化漢字的編碼,通行于中國大陸地區(qū)及新加坡,簡稱國標(biāo)碼。兩個字節(jié)中,第一個字節(jié)(高字節(jié))的值為區(qū)號值加32(20H),第二個字節(jié)(低字節(jié))的值為位號值加32(20H),用這兩個值來表示一個漢字的編碼。UNICODE 碼是微軟提出的解決多國字符問題的多字節(jié)等長編碼,它對英文字符采取前面加“0”字節(jié)的策略實現(xiàn)等長兼容。如 “A” 的 ASCII 碼為0x41,UNICODE 就為0x00,0x41。利用特殊的工具各種編碼之間可以互相轉(zhuǎn)換。

          Java 中文問題的初步認識

          我們基于 Java 編程語言進行應(yīng)用開發(fā)時,不可避免地要處理中文。Java 編程語言默認的編碼方式是 UNICODE,而我們通常使用的數(shù)據(jù)庫及文件都是基于 GB2312 編碼的,我們經(jīng)常碰到這樣的情況:瀏覽基于 JSP 技術(shù)的網(wǎng)站看到的是亂碼,文件打開后看到的也是亂碼,被 Java 修改過的數(shù)據(jù)庫的內(nèi)容在別的場合應(yīng)用時無法繼續(xù)正確地提供信息。

          String sEnglish = “apple”;
          String sChinese = “蘋果”;
          String s = “蘋果 apple ”;

          sEnglish 的長度是5,sChinese的長度是4,而 s 默認的長度是14。對于 sEnglish來說, Java 中的各個類都支持得非常好,肯定能夠正確顯示。但對于 sChinese 和 s 來說,雖然 Java Soft 聲明 Java 的基本類已經(jīng)考慮到對多國字符的支持(默認 UNICODE 編碼),但是如果操作系統(tǒng)的默認編碼不是 UNICODE ,而是國標(biāo)碼等。從 Java 源代碼到得到正確的結(jié)果,要經(jīng)過 “Java 源代碼-> Java 字節(jié)碼-> ;虛擬機->操作系統(tǒng)->顯示設(shè)備”的過程。在上述過程中的每一步驟,我們都必須正確地處理漢字的編碼,才能夠使最終的顯示結(jié)果正確。

          “ Java 源代碼-> Java 字節(jié)碼”,標(biāo)準(zhǔn)的 Java 編譯器 javac 使用的字符集是系統(tǒng)默認的字符集,比如在中文 Windows 操作系統(tǒng)上就是 GBK ,而在 Linux 操作系統(tǒng)上就是ISO-8859-1,所以大家會發(fā)現(xiàn)在 Linux 操作系統(tǒng)上編譯的類中源文件中的中文字符都出了問題,解決的辦法就是在編譯的時候添加 encoding 參數(shù),這樣才能夠與平臺無關(guān)。用法是

          javac -encoding GBK。

          “ Java 字節(jié)碼->虛擬機->操作系統(tǒng)”, Java 運行環(huán)境 (JRE)分英文版和國際版,但只有國際版才支持非英文字符。 Java 開發(fā)工具包 (JDK) 肯定支持多國字符,但并非所有的計算機用戶都安裝了 JDK 。很多操作系統(tǒng)及應(yīng)用軟件為了能夠更好的支持 Java ,都內(nèi)嵌了 JRE 的國際版本,為自己支持多國字符提供了方便。

          “操作系統(tǒng)->顯示設(shè)備”,對于漢字來說,操作系統(tǒng)必須支持并能夠顯示它。英文操作系統(tǒng)如果不搭配特殊的應(yīng)用軟件的話,是肯定不能夠顯示中文的。

          還有一個問題,就是在 Java 編程過程中,對中文字符進行正確的編碼轉(zhuǎn)換。例如,向網(wǎng)頁輸出中文字符串的時候,不論你是用

          out.println(string);還是用

          <%=string%>,都必須作 UNICODE 到 GBK 的轉(zhuǎn)換,或者手動,或者自動。在 JSP 1.0中,可以定義輸出字符集,從而實現(xiàn)內(nèi)碼的自動轉(zhuǎn)換。用法是

          <%@page contentType=”text/html;charset=gb2312” %>

          但是在一些 JSP 版本中并沒有提供對輸出字符集的支持,(例如 JSP 0.92),這就需要手動編碼輸出了,方法非常多。最常用的方法是

          String s1 = request.getParameter(“keyword”);

          String s2 = new String(s1.getBytes(“ISO-8859-1”),”GBK”);

          getBytes 方法用于將中文字符以“ISO-8859-1”編碼方式轉(zhuǎn)化成字節(jié)數(shù)組,而“GBK” 是目標(biāo)編碼方式。我們從以ISO-8859-1方式編碼的數(shù)據(jù)庫中讀出中文字符串 s1 ,經(jīng)過上述轉(zhuǎn)換過程,在支持 GBK 字符集的操作系統(tǒng)和應(yīng)用軟件中就能夠正確顯示中文字符串 s2 。


          Java 中文問題的表層分析及處理
          背景
          開發(fā)環(huán)境 JDK1.15 Vcafe2.0 JPadPro
          服務(wù)器端 NT IIS Sybase System Jconnect(JDBC)
          客戶端 IE5.0 Pwin98 ?span >

          .CLASS 文件存放在服務(wù)器端,由客戶端的瀏覽器運行 APPLET , APPLET 只起調(diào)入 FRAME 類等主程序的作用。界面包括 Textfield ,TextArea,List,Choice 等。

          I.用 JDBC 執(zhí)行 SELECT 語句從服務(wù)器端讀取數(shù)據(jù)(中文)后,將數(shù)據(jù)用 APPEND 方法加到 TextArea(TA) ,不能正確顯示。但加到 List 中時,大部分漢字卻可正確顯示。

          將數(shù)據(jù)按“ISO-8859-1” 編碼方式轉(zhuǎn)化為字節(jié)數(shù)組,再按系統(tǒng)缺省編碼方式 (Default Character Encoding) 轉(zhuǎn)化為 STRING ,即可在 TA 和 List 中正確顯示。

          程序段如下:

          dbstr2 = results.getString(1);
          //After reading the result from DB server,converting it to string.
          dbbyte1 = dbstr2.getBytes(“iso-8859-1”);
          dbstr1 = new String(dbbyte1);

          在轉(zhuǎn)換字符串時不采用系統(tǒng)默認編碼方式,而直接采用“ GBK” 或者 “GB2312” ,在 A 和 B 兩種情況下,從數(shù)據(jù)庫取數(shù)據(jù)都沒有問題。

          II.處理方式與“取中文”相逆,先將 SQL 語句按系統(tǒng)缺省編碼方式轉(zhuǎn)化為字節(jié)數(shù)組,再按“ISO-8859-1”編碼方式轉(zhuǎn)化為 STRING ,最后送去執(zhí)行,則中文信息可正確寫入數(shù)據(jù)庫。

          程序段如下:

          sqlstmt = tf_input.getText();
          //Before sending statement to DB server,converting it to sql statement.
          dbbyte1 = sqlstmt.getBytes();
          sqlstmt = newString(dbbyte1,”iso-8859-1”);
          _stmt = _con.createStatement();
          _stmt.executeUpdate(sqlstmt);
          ……

          問題:如果客戶機上存在 CLASSPATH 指向 JDK 的 CLASSES.ZIP 時(稱為 A 情況),上述程序代碼可正確執(zhí)行。但是如果客戶機只有瀏覽器,而沒有 JDK 和 CLASSPATH 時(稱為 B 情況),則漢字無法正確轉(zhuǎn)換。

          我們的分析:

          1.經(jīng)過測試,在 A 情況下,程序運行時系統(tǒng)的缺省編碼方式為 GBK 或者 GB2312 。在 B 情況下,程序啟動時瀏覽器的 JAVA 控制臺中出現(xiàn)如下錯誤信息:

          Can't find resource for sun.awt.windows.awtLocalization_zh_CN

          然后系統(tǒng)的缺省編碼方式為“8859-1”。

          2.如果在轉(zhuǎn)換字符串時不采用系統(tǒng)缺省編碼方式,而是直接采用 “GBK” 或“GB2312”,則在 A 情況下程序仍然可正常運行,在 B 情況下,系統(tǒng)出現(xiàn)錯誤:

          UnsupportedEncodingException。

          3. 在客戶機上,把 JDK 的 CLASSES.ZIP 解壓后,放在另一個目錄中, CLASSPATH 只包含該目錄。然后一邊逐步刪除該目錄中的 .CLASS 文件,另一邊運行測試程序,最后發(fā)現(xiàn)在一千多個 CLASS 文件中,只有一個是必不可少的,該文件是:

          sun.io.CharToByteDoubleByte.class。

          將該文件拷到服務(wù)器端和其它的類放在一起,并在程序的開頭 IMPORT 它,在 B 情況下程序仍然無法正常運行。

          4.在 A 情況下,如果在 CLASSPTH 中去掉 sun.io.CharToByteDoubleByte.class ,則程序運行時測得默認編碼方式為“8859-1”,否則為 “GBK” 或 “GB2312” 。

          如果 JDK 的版本為1.2以上的話,在 B 情況下遇到的問題得到了很好的解決,測試的步驟同上,有興趣的讀者可以嘗試一下。

          Java 中文問題的根源分析及解決

          在簡體中文 MS Windows 98 + JDK 1.3 下,可以用 System.getProperties() 得到 Java 運行環(huán)境的一些基本屬性,類 PoorChinese 可以幫助我們得到這些屬性。

          類 PoorChinese 的源代碼:

          public class PoorChinese {
          }

          執(zhí)行 java PoorChinese 后,我們會得到:

          系統(tǒng)變量 file.encoding 的值為 GBK ,user.language 的值為 zh , user.region 的值為 CN ,這些系統(tǒng)變量的值決定了系統(tǒng)默認的編碼方式是 GBK 。

          在上述系統(tǒng)中,下面的代碼將 GB2312 文件轉(zhuǎn)換成 Big5 文件,它們能夠幫助我們理解 Java 中漢字編碼的轉(zhuǎn)化:


          import java.io.*;
          import java.util.*;

          public class gb2big5 {

          static int iCharNum=0;

          public static void main(String[] args) {
          System.out.println("Input GB2312 file, output Big5 file.");
          if (args.length!=2) {
          System.err.println("Usage: jview gb2big5 gbfile big5file");
          System.exit(1);
          String inputString = readInput(args[0]);
          writeOutput(inputString,args[1]);
          System.out.println("Number of Characters in file: "+iCharNum+".");
          }

          static void writeOutput(String str, String strOutFile) {
          try {
          FileOutputStream fos = new FileOutputStream(strOutFile);
          Writer out = new OutputStreamWriter(fos, "Big5");
          out.write(str);
          out.close();
          }
          catch (IOException e) {
          e.printStackTrace();
          e.printStackTrace();
          }
          }

          static String readInput(String strInFile) {
          StringBuffer buffer = new StringBuffer();
          try {
          FileInputStream fis = new FileInputStream(strInFile);
          InputStreamReader isr = new InputStreamReader(fis, "GB2312");
          Reader in = new BufferedReader(isr);
          int ch;
          while ((ch = in.read()) > -1) {
          iCharNum += 1;
          buffer.append((char)ch);
          }
          in.close();
          return buffer.toString();
          }
          catch (IOException e) {
          e.printStackTrace();
          return null;
          }
          }
          }

          編碼轉(zhuǎn)化的過程如下:

          GB2312------------------>Unicode------------->Big5

          執(zhí)行 java gb2big5 gb.txt big5.txt ,如果 gb.txt 的內(nèi)容是“今天星期三”,則得到的文件 big5.txt 中的字符能夠正確顯示;而如果 gb.txt 的內(nèi)容是“情人節(jié)快樂”,則得到的文件 big5.txt 中對應(yīng)于“節(jié)”和“樂”的字符都是符號“?”(0x3F),可見 sun.io.ByteToCharGB2312 和 sun.io.CharToByteBig5 這兩個基本類并沒有編好。

          正如上例一樣, Java 的基本類也可能存在問題。由于國際化的工作并不是在國內(nèi)完成的,所以在這些基本類發(fā)布之前,沒有經(jīng)過嚴格的測試,所以對中文字符的支持并不像 Java Soft 所聲稱的那樣完美。前不久,我的一位技術(shù)上的朋友發(fā)信給我說,他終于找到了 Java Servlet 中文問題的根源。兩周以來,他一直為 Java Servlet 的中文問題所困擾,因為每面對一個含有中文字符的字符串都必須進行強制轉(zhuǎn)換才能夠得到正確的結(jié)果(這好象是大家公認的唯一的解決辦法)。后來,他確實不想如此繼續(xù)安分下去了,因為這樣的事情確實不應(yīng)該是高級程序員所要做的工作,他就找出 Servlet 解碼的源代碼進行分析,因為他懷疑問題就出在解碼這部分。經(jīng)過四個小時的奮斗,他終于找到了問題的根源所在。原來他的懷疑是正確的, Servlet 的解碼部分完全沒有考慮雙字節(jié),直接把 %XX 當(dāng)作一個字符。(原來 Java Soft 也會犯這幺低級的錯誤?。?

          如果你對這個問題有興趣或者遇到了同樣的煩惱的話,你可以按照他的步驟 對Servlet.jar 進行修改:

          找到源代碼 HttpUtils 中的 static private String parseName ,在返回前將 sb(StringBuffer) 復(fù)制成 byte bs[] ,然后 return new String(bs,”GB2312”)。作上述修改后就需要自己解碼了:

          HashTable form=HttpUtils .parseQueryString(request.getQueryString())或者

          form=HttpUtils.parsePostData(……)

          千萬別忘了編譯后放到 Servlet.jar 里面。

          關(guān)于 Java 中文問題的總結(jié)

          Java 編程語言成長于網(wǎng)絡(luò)世界,這就要求 Java 對多國字符有很好的支持。 Java 編程語言適應(yīng)了計算的網(wǎng)絡(luò)化的需求,為它能夠在網(wǎng)絡(luò)世界迅速成長奠定了堅實的基礎(chǔ)。 Java 的締造者 (Java Soft) 已經(jīng)考慮到 Java 編程語言對多國字符的支持,只是現(xiàn)在的解決方案有很多缺陷在里面,需要我們付諸一些補償性的措施。而世界標(biāo)準(zhǔn)化組織也在努力把人類所有的文字統(tǒng)一在一種編碼之中,其中一種方案是 ISO10646 ,它用四個字節(jié)來表示一個字符。當(dāng)然,在這種方案未被采用之前,還是希望 Java Soft 能夠嚴格地測試它的產(chǎn)品,為用戶帶來更多的方便。

          posted @ 2008-07-30 17:16 chenkai 閱讀(175) | 評論 (0)編輯 收藏

          網(wǎng)頁中浮動圖片的實現(xiàn)

          <div id="img" style="position:absolute;">
          <a ; target="_blank">
          <img src="http://www.freedown.net/logo.gif"; border="0"></a>
          </div>

          <SCRIPT LANGUAGE="JavaScript">
          <!--
          var xPos = 20;
          var yPos = document.body.clientHeight;
          var step = 1;
          var delay = 30;
          var height = 0;
          var Hoffset = 0;
          var Woffset = 0;
          var yon = 0;
          var xon = 0;
          var pause = true;
          var interval;
          img.style.top = yPos;
          function changePos() {
          width = document.body.clientWidth;
          height = document.body.clientHeight;
          Hoffset = img.offsetHeight;
          Woffset = img.offsetWidth;
          img.style.left = xPos + document.body.scrollLeft;
          img.style.top = yPos + document.body.scrollTop;
          if (yon) {
          yPos = yPos + step;
          }
          else {
          yPos = yPos - step;
          }
          if (yPos < 0) {
          yon = 1;
          yPos = 0;
          }
          if (yPos >= (height - Hoffset)) {
          yon = 0;
          yPos = (height - Hoffset);
          }
          if (xon) {
          xPos = xPos + step;
          }
          else {
          xPos = xPos - step;
          }
          if (xPos < 0) {
          xon = 1;
          xPos = 0;
          }
          if (xPos >= (width - Woffset)) {
          xon = 0;
          xPos = (width - Woffset);
          }
          }
          function www_helpor_net() {
          img.visibility = "visible";
          interval = setInterval('changePos()', delay);
          }
          www_helpor_net();
          //For more,visit:www.helpor.net
          -->
          </script>

          posted @ 2008-07-29 17:20 chenkai 閱讀(669) | 評論 (0)編輯 收藏

          jsp中控件的隱藏

          在html中如何使一個button或text控件不可見?

          <INPUT   type="button"   value="Button"   id=button1   name=button1   disabled>
          <INPUT   type="text"   id=text1   name=text1   readonly>

          <INPUT   type="hidden"   value="Button"   id=button1   name=button1     >  
               
          <INPUT   type="text"   id=text1   name=text1   style="visibility:hidden">  
          <INPUT   type="button"   value="Button"   id=button1   name=button1   style="visibility:hidden">

          可以在jsp中做如下控制:
          <INPUT TYPE="button" NAME="xzdq" value="<<" onClick="selectDept()" >
          <script language="javascript">
           if('<%=userId%>'!= null)document.all.xzdq.style.visibility="hidden";
          </script>

          或者:
          <INPUT TYPE="button" NAME="xzdq" value="<<" onClick="selectDept()" >
          <%
          if(userId != null)
          {
          %>
          <script language="javascript">
           document.all.xzdq.style.visibility="hidden";
          </script>
          <%
          }
          %>

          或者:
          <INPUT TYPE="button" NAME="xzdq" value="<<" onClick="selectDept()" >
          <%
          if(userId != null)
           out.println("<script language=\"javascript\"> document.all.xzdq.style.visibility=\"hidden\";</script>");
          %>

          posted @ 2008-07-29 17:17 chenkai 閱讀(3946) | 評論 (0)編輯 收藏

          <2008年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(2)

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 固阳县| 平凉市| 武鸣县| 望奎县| 郓城县| 安龙县| 盐源县| 肇源县| 静乐县| 黔西| 长岭县| 涟水县| 衡山县| 南澳县| 耒阳市| 新巴尔虎左旗| 浦城县| 云浮市| 灌南县| 额敏县| 加查县| 荆州市| 肥乡县| 玛曲县| 炎陵县| 长海县| 洛川县| 开封县| 墨竹工卡县| 黑河市| 瓮安县| 西城区| 抚州市| 江门市| 张掖市| 安平县| 兰西县| 泰宁县| 平潭县| 文成县| 栾川县|