lizongbo 的 编程学习

http://618119.com

BlogJava 首页 新随笔 联系 聚合 管理
  23 Posts :: 1 Stories :: 78 Comments :: 0 Trackbacks

#

1.首先扩展一个IQ:
源代码来自:
java代码为:
http://cvs.codehaus.org/viewrep/groovy/groovy/modules/xmlrpc/src/main...

import org.jivesoftware.smack.packet.IQ;

/**
 * @author John Wilson
 *
 */

public class JabberRPC extends IQ {

        private final String xml;

        public JabberRPC(final String xml) {
                this.xml = "<query xmlns='jabber:iq:rpc'>\n" + xml + "\n</query>";
        }

        public String getChildElementXML() {
                return this.xml;
        }

}

2.扩展一个IQProvider.
源代码来自:
http://cvs.codehaus.org/viewrep/groovy/groovy/modules/xmlrpc/src/main...
java代码为:
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.StringUtils;
import org.xmlpull.v1.XmlPullParser;

/**
 * @author John Wilson
 *
 */

public class JabberRPCProvider implements IQProvider {

        public IQ parseIQ(final XmlPullParser parser) throws Exception {
                final StringBuffer buffer = new StringBuffer();

                // skip the <query> tag by calling parser.next()
                while (true) {
                        switch (parser.next()) {
                        case XmlPullParser.TEXT:
                                // We need to escape characters like & and <
                                buffer.append(StringUtils.escapeForXML(parser.getText()));
                                break;

                        case XmlPullParser.START_TAG:
                                buffer.append('<' + parser.getName() + '>');
                                break;

                        case XmlPullParser.END_TAG:
                                if ("query".equals(parser.getName())) {
                                        // don't save the </query> end tag
                                        return new JabberRPC(buffer.toString().trim());
                                } else {
                                        buffer.append("</" + parser.getName() + '>');
                                        break;
                                }
                        default:
                        }
                }
        }

}

3.在smack中注册IQProvider .
java代码为:
org.jivesoftware.smack.provider.ProviderManager.addIQProvider("query",
"jabber:iq:rpc", new JabberRPCProvider());

4.smack客户端例子:

try {
                        XMPPConnection con = new XMPPConnection("127.0.0.1", 5222);
                        con.login("username", "password");
                        //注册IQProvider
                        org.jivesoftware.smack.provider.ProviderManager.addIQProvider(
                                        "query", "jabber:iq:rpc", new JabberRPCProvider());
                                        // 监听所有的包
                        con.addPacketListener(new PacketListener() {
                                public void processPacket(Packet packet) {
                                        if (packet instanceof org.jivesoftware.smack.packet.IQ) {
                                                org.jivesoftware.smack.packet.IQ iq =
(org.jivesoftware.smack.packet.IQ) packet;
                                                System.out.println("rpc内容为 " + iq.getChildElementXML());
                                        }
                                }

                        }, new org.jivesoftware.smack.filter.PacketFilter() {
                                public boolean accept(Packet arg0) {
                                        return true;
                                }

                        });
                        con.createChat("xmlrpc.lizongbo.im").sendMessage("测试发送!");
                        JabberRPC jp = new JabberRPC("xmlrpc");
                        jp.setType(org.jivesoftware.smack.packet.IQ.Type.SET);
                        jp.setTo("xmlrpc.lizongbo.im");
                        con.sendPacket(jp);
                        Thread.sleep(25000);
                        con.close();
                } catch (Exception e) {
                        e.printStackTrace();
                }

5.服务端回应一个xmlrpc包:
wildfire中通过插件进行响应:
public void processPacket(Packet p) {
                if (p instanceof IQ) {
                        IQ iq =(IQ)p;
                        IQ niq=IQ.createResultIQ(iq);
                          Element responseElement=niq.setChildElement("query",
"jabber:iq:rpc");
                        try {
                                java.util.Vector v=new  java.util.Vector();
                                v.add("lizongbo  xmpp");
                                v.add("jabber-rpc lizongbo");
                                v.add("xep-0009 lizongbo");
                                XmlRpcResponseProcessor xrrp=new XmlRpcResponseProcessor();
                                String rs= new String( xrrp.encodeResponse(v, "UTF-8"));
                                org.dom4j.Document re=org.dom4j.DocumentHelper.parseText(rs);
                                responseElement.add(re.getRootElement());
                                componentManager.sendPacket(this, niq);
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                }
        }

6.客户端输出结果为:

rpc内容为 <query xmlns='jabber:iq:rpc'>
<methodResponse><params><param><value><array><data><value>lizongbo
xmpp</value><value>jabber-rpc lizongbo</value><value>xep-0009
lizongbo</value></data></array></value></param></params></methodResponse>
</query>

posted @ 2006-12-04 18:16 lizongbo 的编程学习| 编辑 收藏

     摘要: wildfire是支持标准即时通讯协议xmpp的服务端,而linq则是支持xmpp的客户端,通过wildfire和linq可以将Gtalk,MSN,QQ,在一个客户端中联合起来,正文是我的操作步骤,有详细抓图过程。  阅读全文
posted @ 2006-11-29 10:17 lizongbo 的编程学习| 编辑 收藏

在javaeye上看到关于sna的一些讨论,于是对sna很有好奇心,但是google了半天也没有搜索到java webapp中关于sna的开源项目。
于是结合和同学交流之后,动手写了几个java文件,通过过滤器对HttpSession的包装,实现java web应用的sna架构。
使用 snafilter之后,即使web服务器挂了,只要用户还能访问其它web服务器,则可以照常维持session。
代码很简单,但是想到sf上面没有相关的东西,于是昨晚快睡觉的时候就去申请了一个项目,
刚才登录sf的时候,没想到今天就已经被批准了:)

我把代码整理一下之后,就把它传到sf上来:)

这个项目的名称是:snafilter。
英文简介是: snafilter is a J2EE servlet filter which wraped HttpSession to supports share nothing architecture 。
这句说明是仿照另外一个开源过滤器(http://pjl-comp-filter.sourceforge.net/)改写的。
项目的地址是:
http://sourceforge.net/projects/snafilter

目前实现的snafilter是,sna会话id基于cookie,使用Memcached Server存放sna信息。
通过snafilter可以避免session复制的消耗,而且不需要黏性会话的配置,就可以使得多个servlet容器(可以同时包含不同的servlet容器,比如tomcat和resin同时使用)可以结合在一起实现类似failover的效果。
基本上可以随时重起tomcat而不影响客户端用户:)

在发布第一个版本之后,打算再加入其它的一些特性,欢迎大家交流意见。
ps1:我不太会使用sf的一些功能,欢迎大家分享经验。
ps2:前段时间向tomcat反映的一个小意见,被新版本的tomcat采纳了,很开心:)
http://tomcat.apache.org/tomcat-5.5-doc/changelog.html
39674: Support JRockit JVM in service.bat script, as suggested by lizongbo. (yoavs)
http://issues.apache.org/bugzilla/show_bug.cgi?id=39674

现在深刻体会到我的英语真烂,以后得多锻炼英语了:)

posted @ 2006-10-26 00:54 lizongbo 的编程学习| 编辑 收藏

     摘要: 当在同一个网页里引入10多个js文件之后,
各js中的同名函数就很容易冲突了。
比如xxx库里写了个addCssStyle方法,
yyy类库里也写了个addCssStyle方法,
而这两个方法的具体实现又有一定差别。
那么同时引用这两个组件的时候,函数冲突之后导致页面效果发生变化,
调试和修改都是非常痛苦的,如果为了避免冲突,
而放弃引用一些优秀的组件,那更是让人郁闷的事情。

为此,在封装javascript组件库的时候,请使用命名空间来避免冲突。
将所有的方法和变量都要按包名类名的方式来写。
(这个时候写代码的感觉和封装java的util方法一样方便,呵呵) (详细示例代码见文章具体内容)  阅读全文
posted @ 2006-06-19 15:39 lizongbo 的编程学习| 编辑 收藏

   Spring BeanDoc 使用

   Spring BeanDoc 是一个根据spring的bean配置文件生成文档的工具。

1.下载:
spring-beandoc-0.7.0:
http://opensource.atlassian.com/confluence/spring/download/attachments/993/spring-beandoc-0.7.0.tgz?version=1

参考: http://opensource.atlassian.com/confluence/spring/display/BDOC/Home
graphviz-2.8:

http://www.graphviz.org/pub/graphviz/ARCHIVE/graphviz-2.8.exe
参考: http://www.graphviz.org/Download_windows.php
apache-ant-1.6.5:
http://www.eu.apache.org/dist/ant/binaries/apache-ant-1.6.5-bin.zip

2.安装,解压spring-beandoc-0.7.0.tgz和apache-ant-1.6.5-bin.zip到d:/Java/
设置环境变量:
ANT_HOME=D:\java\apache-ant-1.6.5
Path=D:\jdk1.5.0_06\bin;D:\java\apache-ant-1.6.5\bin;........
运行graphviz-2.8.exe,安装到D:\Programs\ATT。

3.到D:\java\spring-beandoc-0.7.0\src\org\springframework\beandoc\output\i18n下
增加中文资源文件labels_zh.properties ,然后对照翻译,
#-----------------------------------------
# @since 1.0

i18n-generated=beandoc \u751F\u6210\u4E86
i18n-filelist=files making up this application context
i18n-description=\u63CF\u8FF0
i18n-attributes=\u5C5E\u6027
i18n-constructorargs=\u6784\u9020\u53C2\u6570
i18n-allTitle=\u6240\u6709 Beans
i18n-summaryTitle=beans\u6458\u8981
i18n-detailTitle=beans\u8BE6\u60C5
i18n-innerbean=\u533F\u540D\u5185\u90E8bean
i18n-home=\u9996\u9875
i18n-summary=\u6458\u8981
i18n-detail=\u8BE6\u60C5
i18n-abstractbean=\u62BD\u8C61 bean
i18n-deps=\u4F9D\u8D56, \u5C5E\u6027\u503C \u548C \u65B9\u6CD5 \u6CE8\u5165
i18n-backtotop=\u9000\u56DE\u5230\u9876\u90E8
i18n-name=\u540D\u5B57
i18n-bean=bean
i18n-argtypes=\u53C2\u6570\u7C7B\u578B

#-----------------------------------------

再到D:\java\spring-beandoc-0.7.0\下运行build.bat。

4.到D:\java\spring-beandoc-0.7.0\samples\
编辑beandoc.properties,

第50行改为:i18n.locale=zh
第60行改为:compiler.dotExe=d:/Programs/ATT/GraphViz/bin/dot.exe

5.清空 D:\java\spring-beandoc-0.7.0\samples\jpetstore和 D:\java\spring-beandoc-0.7.0\samples\petclinic,复制spring配置文件
到D:\java\spring-beandoc-0.7.0\samples\jpetstore

6.然后运行D:\java\spring-beandoc-0.7.0\samples\runbeandoc-cli.bat
需要带参数:
D:\java\SPRING~1.0\samples>runbeandoc-cli.bat beandoc.properties

7.然后打开D:\java\spring-beandoc-0.7.0\target\sample-output\index.html.
就可以看到生成好的文档了。

posted @ 2006-06-13 22:50 lizongbo 的编程学习| 编辑 收藏

由于项目中有需求要一个blog功能,在大致看了下dlog4j和roller之后。

通过使用blogjava和codelphi的blog的体会。
参考的.text的样子,决定照虎画猫自己写一个。
目前已经完成大部分功能。

通过http://222.66.24.243/webblog/debug/init.jsp这个地址自动登录,然后进行blog管理。

http://222.66.24.243/webblog/u/demouser 察看效果。

前台界面使用了jstl和oscache标签。开发时间大约一个星期
后台界面,采用的ajax的方式。开发时间大约两个星期。
页面风格样式主题照搬的codelphi的blog。

由于现在数据量小,现在执行一个页面的时间大约是200毫秒,在oscache缓存之后是20毫秒。
暂时还推断不了数据量大了之后会不会出现csdn和donews那样的性能问题。
由于对页面缓存的时间是一个小时,只在回复文章的时候做了即时刷新缓存。
因此其它地方的修改,需要过段时间才能够看到效果。


欢迎大家帮忙测试,并欢迎在此发表意见。





posted @ 2006-05-10 10:16 lizongbo 的编程学习| 编辑 收藏

     摘要: 受 charon@xxx 的回复的提示,结合myeclipse生成 pojo的思路,对我的代码生成器进行改进,作以下处理。
谢谢 charon@xxx 。  阅读全文
posted @ 2006-04-26 14:08 lizongbo 的编程学习| 编辑 收藏

     摘要: 在此写一下我自己的代码生成器的设计和一点体会。
  阅读全文
posted @ 2006-04-25 22:47 lizongbo 的编程学习| 编辑 收藏

很奇怪,很多人都说proxool很好,
但是搜索spring中配置proxool作 数据源连接池的资料却几乎找不到详细点的。

因此自己整理如下:

  先下载:
 
  http://surfnet.dl.sourceforge.net/sourceforge/proxool/proxool-0.9.0RC2.zip


  web.xml

-------------------------


  <servlet>
    <servlet-name>proxoolServletConfigurator</servlet-name>
    <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
    <init-param>
      <param-name>xmlFile</param-name>
      <param-value>WEB-INF/proxool.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>proxooladmin</servlet-name>
    <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>proxooladmin</servlet-name>
    <url-pattern>/proxooladmin</url-pattern>
  </servlet-mapping>


-------------------------

  proxool.xml

-------------------------
<?xml version="1.0" encoding="UTF-8"?>
<proxool-config>
  <proxool>
    <alias>blogdb</alias>
    <driver-url>jdbc:oracle:thin:@127.0.0.1:1521:ORADB</driver-url>
    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
    <driver-properties>
      <property name="user" value="lizongbo"/>
      <property name="password" value="password"/>
    </driver-properties>
    <maximum-connection-count>10</maximum-connection-count>
    <house-keeping-test-sql>select 1 from dual</house-keeping-test-sql>
  </proxool>
</proxool-config>

spring里:
两种配置:
a:  <!-- 与上面的proxool以及web.xml里结合使用-->
    <bean id="mainDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
    <value>org.logicalcobwebs.proxool.ProxoolDriver</value>
    </property>
    <property name="url">
    <value>proxool.blogdb</value>
    </property>
    </bean>

b:<!-- 单独的类似dbcp的使用-->
  <bean id="mainDataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource" destroy-method="close">
    <property name="driver">
      <value>oracle.jdbc.driver.OracleDriver</value>
    </property>
    <property name="driverUrl">
      <value>jdbc:oracle:thin:lizongbo/password@127.0.0.1:1521:ORADB</value>    
 <!--用户名和密码写在一起才调用成功,不然会报 调用无效的参数 错误,下面设置用户名和密码的property好像是无效的,其它数据库也是这样
 比如mysql的也要把用户名和密码写在url里:<property name="driverUrl" value="jdbc:mysql://localhost:3306/blogdb?user=lizongbo&amp;password=lizongbo" />
 -->
    </property>
    <property name="user"> <!-- 必须在这里也设置,但是 proxool却不使用它,或许是个bug-->
      <value>lizongbo</value>
    </property>
    <property name="password"> <!-- 必须在这里也设置,但是 proxool却不使用它,或许是个bug-->
      <value>lizongbo</value>
    </property>
    <property name="alias">
      <value>lizongbo</value>
    </property>
    <property name="houseKeepingSleepTime">
      <value>90000</value>
    </property>
    <property name="prototypeCount">
      <value>5</value>
    </property>
    <property name="maximumConnectionCount">
      <value>100</value>
    </property>
    <property name="minimumConnectionCount">
      <value>10</value>
    </property>
    <property name="trace">
      <value>true</value>
    </property>
    <property name="verbose">
      <value>true</value>
    </property>
  </bean>


   
posted @ 2006-04-07 14:17 lizongbo 的编程学习| 编辑 收藏

有同事讨论到关于url编码的问题。
因此总结以下几点方法供大家参考。
首先,对于post请求的时候,通过过滤器就可以搞定,以下的方法主要是针对get方式的乱码处理。

1. 手工对字符串编码解码的方法为:
java.net.URLEncoder.encode("测试","UTF-8");
java.net.URLDecoder.decode("%E6%B5%8B%E8%AF%95%26%3Faaa","UTF-8");
这个方法适用于自己从原始字符串中进行解码处理。

2. tomcat服务器的处理url编码的方法:

修改tomcat的server.xml增加指定的编码,以代替tomcat默认的ISO-8859-1。
需要增加的参数为:URIEncoding,
比如下面的例子是制定解码使用UTF-8,
<Connector port="8080"
maxThreads="800" minSpareThreads="25" maxSpareThreads="100"
enableLookups="false" redirectPort="8443" acceptCount="0"
debug="0" connectionTimeout="20000" URIEncoding="UTF-8"
disableUploadTimeout="true" />
如果用到了apache与tomcat 的整合,则还需要:
<Connector port="8009" URIEncoding="UTF-8"
enableLookups="false" redirectPort="8443" debug="0"
protocol="AJP/1.3" maxThreads="1100" minSpareThreads="25" maxSpareThreads="100" acceptCount="0"/>
(这个方法最简单方便,但是使用这种的方法之后,代码中就不需要也能有new String(strvalue.getBytes("ISO8859-1","GBK"); 这样的处理方式)

3.对于已经部署的系统,可能已经有其他同事对编码使用了
new String(strvalue.getBytes("ISO8859-1","GBK");
这样的方法作了处理,这个时候使用第二种方法就可能会影响到其它模块的正常使用,

因此,我们可以自己重新解析queryString我封装了几个方法。使用重新封装的方法可以在不影响原来系统的情况下,正确的获得参数。

封装的代码如下,供大家参考:



/**
* 从请求的url字符串中解析参数,当request.getParameterValues()取得的参数值编码值不正确的时候可以使用该方法
* @param request HttpServletRequest
* @param paramName String
* @return String[] 返回多个同参数名的值
*/
public static String[] getParamsFromQueryString(HttpServletRequest request,
String paramName) {
return getParamsFromQueryString(request.getQueryString(), paramName);
}

/**
* 从请求的url字符串中解析参数,当request.getParameterValues()取得的参数值编码值不正确的时候可以使用该方法
* @param request HttpServletRequest
* @param paramName String
* @return String[]
*/
public static String getParameterFromQueryString(HttpServletRequest request,
String paramName) {
return getParameterFromQueryString(request.getQueryString(), paramName);
}

/**
* 从请求的url字符串中解析参数,当request.getParameter()取得的参数值编码值不正确的时候可以使用该方法
* @param queryString String
* @param paramName String
* @return String 只返回一个值
*/
public static String getParameterFromQueryString(String queryString,
String paramName) {
String[] s = getParamsFromQueryString(queryString, paramName);
if (s != null && s.length >= 1) {
return s[0];
}
return null;
}

/**
* 从请求的url字符串中解析参数,当request.getParameter()取得的参数值编码值不正确的时候可以使用该方法
* @param queryString String
* @param paramName String
* @return String[] 返回多个同参数名的值
*/
public static String[] getParamsFromQueryString(String queryString,
String paramName) {
if (paramName == null || paramName.length() < 1 || paramName == null ||
paramName.length() < 1) {
return new String[0];
}
List rsl = new ArrayList();
String params[] = queryString.split("&");
for (int i = 0; i < params.length; i++) {
// System.out.println(params[i]);
if (params[i] != null && params[i].startsWith(paramName + "=")) {
try {
rsl.add(java.net.URLDecoder.decode(params[i].substring(paramName.
length() +
1), "UTF-8")); //根据需要修改自己要使用的编码。
}
catch (UnsupportedEncodingException ex) {
}
}
}
return (String[]) rsl.toArray(new String[0]);
}

public static void main(String[] args) {
//该例子演示解码。
//jsp和servlet中调用
// System.out.println(getParameterFromQueryString(request.getQueryString(), "q"));
//该例子示意的是gogole的url中的queryString。
System.out.println(getParameterFromQueryString(
"hl=zh-CN&newwindow=1&q=%E6%B5%8B%E8%AF%95%26%3Faaa&meta=", "q"));
}


posted @ 2006-04-07 14:10 lizongbo 的编程学习| 编辑 收藏

仅列出标题
共3页: 上一页 1 2 3 下一页