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.blogjava.net/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.blogjava.net/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