lizongbo 的 編程學習

          http://618119.com

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            23 Posts :: 1 Stories :: 78 Comments :: 0 Trackbacks

          #

          關于 java (apache xmlrpc) ,delphi (delphi xml-rpc),javascript(jsolait)操作xmlrpc的幾點注意事項。

          (lizongbo原創,轉載請注明出處。)
          A. java操作xmlrpc.
          可以使用 apache xmlrpc http://ws.apache.org/xmlrpc/

          1. org.apache.xmlrpc.XmlRpc.setDebug(true);可以打開調試模式,可以看到一些詳細的xmlrpc解析處理日志。
          2. 不支持值為null,支持的java類型為:Integer,Boolean,String,Double,java.util.Date(支持其子類),byte[],java.util.Vector,java.util.Hashtable
          (http://ws.apache.org/xmlrpc/types.html? apache xmlrpc 對java類型作了擴展,但是如果要考慮其它編程語言的調用,不建議使用擴展的類型)


          B. delphi操作xmlrpc的庫是delphixml-rpc:http://sourceforge.net/projects/delphixml-rpc/
          (網上有人提到過codepunk,但是現在已經無法下載.http://www.codepunk.com/xmlrpc1_7_6.zip ,參考:http://www.delphibbs.com/keylife/iblog_comment.asp?xid=870)
          于是選擇了delphixml-rpc,實際使用中遇到以下一些問題,
          1.漢字處理的問題。 delphi作客戶端,? java作服務端,產生
          Hello, 你好 , test  汉字"不能夠轉換成"Hello, 你好 , test 漢字"
          的問題, 解決方法如下:
          ?
          xmlrpcparser
          1554行,
          CHR改成widechar
          如下:
          ????????? THEN CurContent := CurContent + widechar (StrToIntDef ('$'+Copy (Name, 3, MaxInt), 32))
          ????????? ELSE CurContent := CurContent + widechar (StrToIntDef (Copy (Name, 2, MaxInt), 32));


          對于sf上最新的xmlrpc包,則需要修改LibxmlPraser.pas對應地方的代碼
          2.空字符串(非null)的解析問題。
          java 的代碼: Hashtable struct = new Hashtable();
          ??????? struct.put("type", new Integer(0));
          ??????? struct.put ("id", "0"); //如果這樣寫 struct.put("id", ""); ,就會導致結構體錯亂 ,取不到第一個 struct
          解決辦法,通過一個約定的字符串“nil”來表示空字符串。

          3. 使用ssl遇到的問題:
          tomcat的 ssl配置為:
          ??? <Connector port="8083"
          ?????????????? maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
          ?????????????? enableLookups="false" disableUploadTimeout="true"
          ?????????????? acceptCount="100" scheme="https" secure="true"
          ?????????????? clientAuth="false" sslProtocol="TLS"
          ?????????? keystoreFile="conf/ca/.keystore"
          ?????????? keystorePass="password">
          ???? </Connector>
          ?
          而delphi的xmlrpc調用會出問題,因此需要修改源代碼:
          在XmlRpcClient.pas的第321行之后加上下面兩行代碼:
          ?
          ??????? IdSSLIOHandlerSocket.SSLOptions.Mode := sslmUnassigned;
          ??????? IdSSLIOHandlerSocket.SSLOptions.Method := sslvTLSv1;
          ?
          ?(如果tomcat使用了apr,則ssl配置是不一樣的,這種情況下的delphi調用,我們沒測試過)
          4.亂碼導致結構體解析失敗
          ?
          如果結構體的string里有不可識別的字符,會導致結構體解析失敗,
          因此,在傳輸的內容為不可預見的情況下(比如用戶發送的千奇百怪的短消息),
          建議用byte傳送(實際工作中遇到這樣的情況并總結出來的。)
          服務端 :struct.put ("msg", "測試短消息"); ---> struct.put ("msgbyte", "測試短消息".getBytes());
          客戶端delphi代碼改用asBase64str方法來還原為string.


          (以上均是實際工作中遇到的問題。 )

          C .jsolait的xmlrpc庫是javascript的操作xmlrpc的,非常簡單.

          多個參數的調用可以放在一個數組,也可以分別傳入,同jdk1.5的可變參數(Variable Arguments)。
          如果只傳一個參數,而這個參數是個數組,需要這樣寫:

          var xmlrpc=null;
          ?try{
          ??? var xmlrpc = importModule("xmlrpc");
          ?}catch(e){
          ??? reportException(e);
          ??? throw "importing of xmlrpc module failed.";
          ?}
          ?var addr = "http://lizongbo:808/lizongbo/xmlrpc";
          ?var methods = ["lizongbo.testOneArray"];
          ?var rslt;
          ?var params = new Array();
          ?params[0] = "0311112";
          ?params[1] = "awsasaas";
          ?params[2] = "awsasaas";
          ?try{
          ?????? var service = new xmlrpc.ServiceProxy(addr, methods);
          ?????? rslt = service.lzbrpc.testOneArray([params]);//用中括號括起來,否則會被解析為三個傳入參數的調用
          ?????? ///service.lzbrpc.testOneArray(params) 等同于service.lzbrpc.testOneArray(params[0],params[1],params[2]);

          ?????? 返回結果里如果只有一個值,可以直接在用rslt,如果有多個值,
          ?????? 比如下面這個結構體, 則可以用rslt.flag,rslt.info,rslt.struct.version來分別得到對應的值。
          ?????? (符合dom)
          // var str="" + rslt.flag+' xx '+rslt.info+' yy '+rslt.struct.version ;
          // 或者var str="" + rslt['flag']+' xx '+rslt['info']+' yy '+rslt['struct']['version'];
          //得到的結果是"1 xx 成功 yy 123.beta "
          參考 : http://www.aygfsteel.com/mstar/archive/2005/06/07/5657.aspx

          ?

          D . 調試xmlrpc,有一個非常優秀的工具:
          http://torrez.net/projects/konstructor/Konstructor.exe
          來自:
          http://torrez.net/archives/xmlrpc_request_builder.php

          缺點,只能夠連接類似 http://lizongbo.com/xmlrpc的Endpoint
          不支持https,也不支持除80外的其它端口

          (lizongbo原創,轉載請注明出處。)

          posted @ 2006-03-18 23:49 lizongbo 的編程學習| 編輯 收藏

          在一篇blog里我在回復里寫了displaytag1.1大數據量分頁顯示的索引存在bug
           http://www.aygfsteel.com/zJun/archive/2006/02/27/32723.html

          后來下載源代碼下來找到了修改bug的地方。
          并把代碼發到 displaytag的jira里了,具體地址在:
          http://jira.codehaus.org/browse/DISPL-303
           (有人已經提交這個bug了)


          org.displaytag.pagination.SmartListHelper.java
          把下面兩個方法的代碼改寫如下:

               public int getFirstIndexForCurrentPage() {
                  return (this.currentPage - 1) * this.pageSize;
              }

              /**
               * Returns the index into the master list of the last object that should appear on the current page that the user is
               * viewing.
               * @return int
               */
              protected int getLastIndexForCurrentPage() {
                  if (this.partialList) {
                      return (getFirstIndexForCurrentPage()) +
                              Math.min(this.pageSize - 1, this.fullList.size() - 1);
                  } else {
                      return getLastIndexForPage(this.currentPage);
                  }
              }


          順便記錄 displaytag 1.1 使用Partial Lists大數據量分頁的例子:

          在近量不改動現有代碼的基礎上來使用displaytag結合數據庫分頁.

          1.先設置總頁數:

          <%
             Integer totalNum = new Integer(919);
          request.setAttribute("totalNum",totalNum);//設置總記錄條數
          %>

          2.配置displaytag的 兩個屬性:partialList="true" size="totalNum"
          比如:
            <display:table id="testtbid"  name="requestScope.testlist" pagesize="20" partialList="true" size="totalNum">

          3.在jsp中獲得翻頁信息的代碼:

          <%

          下面代碼是取得翻頁數

          //如果沒有為table設置 id那么就要寫成ParamEncoder(null);
            String rpname = new org.displaytag.util.ParamEncoder("testtbid")
                .encodeParameterName(
                    org.displaytag.tags.TableTagParameters.PARAMETER_PAGE);
            System.out.println("當前頁數:" + rpname + " = " +
                               request.getParameter(rpname));
                 //然后根據當前頁數去從數據庫中取出相應數據。

           

          //see: http://displaytag.sourceforge.net/11/displaytag/apidocs/org/displaytag/tags/TableTagParameters.html

          %>
          表格分頁導航條里的分頁鏈接個數默認是8個,可以通過下面的代碼來更改
          //在<display:table>標簽內
              <display:setProperty name="paging.banner.group_size" value="20"/>
          //</display:table>

          當然也可以通過實現 org.displaytag.pagination.PaginatedList接口來完成這個要求。
          更多信息,請參考:
          http://displaytag.sourceforge.net/11/tut_externalSortAndPage.html

          利用內置el在displaytag里顯示checkbox非常簡單:

                               <display:column title='select User' >
           <input type="checkbox" name="firstName"  value="{testtbid.name}" />${testtbid.name}
          </display:column>

          posted @ 2006-03-14 21:01 lizongbo 的編程學習| 編輯 收藏

          在對一個map進行迭代遍歷并刪除一些符合條件的鍵值對的時候,容易出現

               java.util.ConcurrentModificationException 這個異常。
          Exception in thread "main" java.util.ConcurrentModificationException
           at java.util.HashMap$HashIterator.nextEntry(HashMap.java:787)
           at java.util.HashMap$KeyIterator.next(HashMap.java:823)

          解決辦法如下:

          import java.util.*;

          public class TestMap {
            public TestMap() {
            }

            public static void main(String[] args) {
              java.util.Map m = new java.util.HashMap();
              m.put("aaa", "lizongbo ");
              m.put("bbb", " lizongbo");
              m.put("ccc", "lizongbo  ");
              m.put("ddd", "  lizongbo");
              m.put("eee", "lizongbo");
              m.put("fff", "lizongbo");
              m.put("ggg", "lizongbo");
              m.put("adads", "lizongbo");
              m.put("dffd", "lizongbo");
              m.put("dcxv", "lizongbo");
              m.put("lizongbo", "lizongbo");
              m.put("ert", "lizongbo");
              m.put("544", "lizongbo ");
              Iterator iterator = m.keySet().iterator();
              while (iterator.hasNext()) {
                String sessionId = (String) iterator.next();
                if ("ggg".equals(sessionId) || "lizongbo".equals(sessionId) ||
                    "544".equals(sessionId)) {
                  iterator.remove();       //這行代碼是關鍵。
                  m.remove(sessionId);
                }
              }
              System.out.println(m.get("ggg"));
              System.out.println(m.get("lizongbo"));
              System.out.println(m.get("544"));
            }

                  相關參考: http://ldfren.bosinet.com/archives/113.html
          http://gceclub.sun.com.cn/yuanchuang/week-14/iterator.html

          posted @ 2006-02-27 10:12 lizongbo 的編程學習| 編輯 收藏

          僅列出標題
          共3頁: 上一頁 1 2 3 
          主站蜘蛛池模板: 崇礼县| 镇康县| 远安县| 米林县| 西乡县| 中宁县| 盐津县| 彩票| 弋阳县| 合阳县| 岗巴县| 射阳县| 灌阳县| 黄大仙区| 平山县| 彰武县| 四子王旗| 铁力市| 双鸭山市| 襄城县| 大安市| 临沂市| 吉林市| 台前县| 长海县| 方山县| 拜城县| 定安县| 福安市| 谢通门县| 隆昌县| 大余县| 东乡| 林口县| 桂林市| 岗巴县| 达尔| 乌兰浩特市| 繁峙县| 鹤岗市| 商河县|