• cmpp 2.0短信程序,java源代码

    本程序用了以下几个开源项目,需要把相应的jar文件拷贝到这个war\WEB-INF\lib目录.

    hibernate-2.1;
    quartz-1.4.4;
    webwork-2.1.7;

    还有相应的数据库的驱动包, ms sql server我用的是jtds-1.0.2

    cmpp2.0短信程序,java源代码,包括发送短信的jsp
  • package com.kelefa.glidewindow;

    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.Map;

    /**
    * 滑动窗口.
    * 有些工作(例如网络通信)需要回应,但不需要一个一个的等待回应,可并发的进行,但需要控制流量,
    * 滑动窗口是比较好的方法.
    *
    * cmpp消息采用并发方式发送,加以滑动窗口流量控制,窗口大小参数W可配置:setSize( int size ),
    * 现阶段建议为16,即接收方在应答前一次收到的消息最多不超过16条。
    *
    *
    * <p>Copyright: Copyright (c) 2005</p>
    * @author 杨杰荣
    * @version 1.0
    */
    public class GlideWindow extends Thread
    {
    private int size = 10;
    private Map todo = new LinkedHashMap();
    private Map wait = new HashMap();

    public GlideWindow()
    {
    start();
    // try{
    // Thread.sleep( 100 );
    // }
    // catch ( InterruptedException ex ){
    // ex.printStackTrace();
    // }
    }

    public void run()
    {
    synchronized ( this )
    {
    for (;;)
    {
    while ( wait.size() >= size || todo.size()==0 )
    {
    try {
    this.wait();
    }
    catch ( InterruptedException ignored ) {
    }
    }

    Object key = ( Object ) todo.keySet().iterator().next();
    Runnable job = ( Runnable ) todo.remove( key );
    wait.put( key, job );
    System.out.println( "put to wait " + key );
    job.run();
    }
    }
    }


    public synchronized void addJob( Object key, Runnable job )
    {
    System.out.println("add " + key);
    todo.put( key, job );
    notifyAll();
    }

    public synchronized Object remove( Object key )
    {
    System.out.println("remove "+key);
    notifyAll();
    return wait.remove(key);
    }

    public void setSize( int size )
    {
    this.size = size;
    }

    public int getSize( )
    {
    return size;
    }

    public static void main(String[] args)
    {
    GlideWindow glideWindow = new GlideWindow();
    glideWindow.setSize( 10 ); // 窗口大小

    // 以下10个任务都被执行,都是没有回应
    for ( int i = 0; i < 10; i++ )
    {
    glideWindow.addJob(
    new Integer( i ),
    new Runnable()
    {
    public void run()
    {
    System.out.println( "task running" );
    }
    } );
    }

    // 窗口已满,"waiting"这个任务不会执行,处于等待状态
    glideWindow.addJob(
    "waiting",
    new Runnable()
    {
    public void run()
    {
    System.out.println( "task running" );
    }
    } );

    // 对0任务作出回应,"waiting"这个任务可以执行了
    glideWindow.remove( new Integer( 0 ) );
    }
    }
  • 1。通过cmpp协议接收短信不是在自己的服务器的7910端口监听,而是链接到移动短信服务器的7910端口

    2。短信内容的长度是byte的类型,8个字节,应该是无符号的,但是java的byte是有符号的,所以最大值是127,当大于127时长度就小于0了,所以这两天一直郁闷为什么发长短信就死在那里,解决:

    byte tmpLen = in.readByte();
    msg_Length = tmpLen;
    if (msg_Length<0) msg_Length += 256;
  • 系统需要定时的做一个任务,我用os的quartz,quartz应该是这样实现的吧,我没有研究过:

    1. new或者从线程池里get一个线程
    2. 让这个线程执行具体的任务:((Job)class.newInstance()).execute(...);

    看了webwork的源代码,每一个IoC对象都根据components.xml配置的scope放在相应的ComponentManager里,即request,session,application3个范围里。因为quartz线程不是一个HTTP请求,不存在request对象,并没有经过com.opensymphony.webwork.lifecycle.RequestLifecycleFilter这个过滤器,无法找到ComponentManager,所以webwork的IoC在这里就用不了。

    但是整个系统都是IoC来设置component的,在这里硬编码?

    暂时这样解决:

    1. 修改ComponentUtil类,加上一个静态变量:ServletContext application,修改initializeObject方法,如果是quartz线程调用则用application得到ComponentManager并初始化对象
    2. 通过一个Servlet启动quartz,在启动前加上:
    ComponentUtil.application = servletConfig.getServletContext();
    ComponentUtil.initializeObject(this); // 初始化dao

    public class ComponentUtil
    {
    public static ServletContext application;

    public static Object initializeObject(Object obj)
    {
    ComponentManager container =
    (ComponentManager) ActionContext.getContext().get(
    "com.opensymphony.xwork.interceptor.component.ComponentManager");

    if (container == null && application != null)
    {// 由quartz的任务线程调用,因为它不是一个request请求,上一步的container等于null
    container = ( ComponentManager )
    application.getAttribute( ComponentManager.COMPONENT_MANAGER_KEY );
    }

    if (container != null) {
    container.initializeObject(obj);
    }

    return obj;
    }
    }

    不知还有没有更好的办法???
  • 在webwork中有2种class可以用IoC来配置系统中的Components,一种是Action对象,另一种是Components对象。但是很多时候我们在别的地方也要用到IoC,要不然一部分是用IoC来动态设置Components,另一部分却要硬编码实现,跟没有使用IoC一样,还好还有别的方法:

    // 初始化component的工具类
    public class ComponentUtil
    {
    public static Object initializeObject(Object obj)
    {
    ComponentManager container =
    (ComponentManager) ActionContext.getContext().get(
    "com.opensymphony.xwork.interceptor.component.ComponentManager");

    if (container != null) {
    container.initializeObject(obj);
    }

    return obj;
    }
    }

    在需要用到IoC对象的类,实现具体Aware接口,在使用IoC对象前,加上这个:
    ComponentUtil.initializeObject(this);
    当然一个对象只要调用一次就可以了,而且不要放在构造函数里。
  • 在webwork中有2种class可以用IoC来配置系统中的Components,一种是Action对象,另一种是Components对象,当然Action要声明ComponentInterceptor拦截器,ComponentInterceptor拦截器会帮你初始化在components.xml中定义的对象,例如:

    <component>
    <scope>application</scope>
    <class>com.skylink.greenChannel.operation.hibernate.UserDAO</class>
    <enabler>com.skylink.greenChannel.operation.UserDAOAware</enabler>
    </component>

    上面是用hibernate实现的DAO对象,如果你觉得直接用jdbc更好,只需把上面的配置改成这样就行了:

    <component>
    <scope>application</scope>
    <class>com.skylink.greenChannel.operation.jdbc.UserDAO</class>
    <enabler>com.skylink.greenChannel.operation.UserDAOAware</enabler>
    </component>

    UserDAOAware.java:
    public interface UserDAOAware
    {
    public void setUserDao(AbstractDAO dao);
    }
    当然,两个UserDAO都必须实现AbstractDAO接口,用到UserDAO的Action类要实现UserDAOAware接口。