订阅本站

Struts使用举例

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

1.  logic:empty           该标签是用来判断是否为空的。如果为空,该标签体中嵌入的内容就会被处理。该标签用于以下情况:
         1)当Java对象为null时;
         2)当String对象为”"时;
         3)当java.util.Collection对象中的isEmpty()返回true时;
         4)当java.util.Map对象中的isEmpty()返回true时。
          eg.
            <logic:empty   name=”userList”> 
              … 
           </logic:empty>
           该句等同于:
           if   (userList.isEmpty())   { 
                 … 
           } 
   2.  logic:notEmpty
          该标签的应用正好和logic:empty标签相反,略。
   3. logic:equal
          该标签为等于比较符。
          eg1. 比较用户的状态属性是否1,若为1,输出”启用”;
                 <logic:equal   name=”user”   property=”state”   value=”1″>
                     启用
                 </logic:equal>
         eg2. 如果上例中的value值是动态获得的,例如需要通过bean:write输出,因struts不支持标签嵌套,可采用EL来解决该问题。
                <logic:equal   name=”charge”   property=”num”   value=”${business.num}”> 
                    ……
                </logic:equal>
   4. logic:notEqual
          该标签意义与logic:equal相反,使用方法类似,略。
    5. logic:forward
          该标签用于实现页面导向,查找配置文件的全局forward。
          eg. <logic:forward name=”index”/>
    6. logic:greaterEqual
          为大于等于比较符。
          eg. 当某学生的成绩大于等于90时,输出“优秀”:
               <logic:greaterEqual name=”student” property=”score” value=”90″>
                  优秀
            </logic:greaterEqual>
    7. logic:greaterThan
          此为大于比较符,使用方法同logic:greaterEqual,略;
    8. logic:lessEqual
          此为小于等于比较符,使用方法同logic:greaterEqual,略;
    9. logic:lessThan
          此为小于比较符,使用方法同logic:greaterEqual,略;
    10. logic:match
          此标签比较对象是否相等;
          eg1. 检查在request范围内的name属性是否包含”amigo”串:
            <logic:match name=”name” scope=”request” value=”amigo”>
                  <bean:write name=”name”/>中有一个“amigo”串。
            </logic:match>
         eg2. 检查在request范围内的name属性是否已“amigo”作为起始字符串:
           <logic:match name=”name” scope=”request” value=”amigo” location=”start”>
               <bean:write name=”name”/>以“amigo”作为起始字符串。
            </logic:match>
         eg3.
            <logic:match header=”user-agent” value=”Windows”>
               你运行的是Windows系统
            </logic:match>
    11.  logic:notMatch
          此标签用于比较对象是否不相同,与logic:match意义相反,使用方法类似,略。
     12. logic:messagePresent
          该标签用于判断ActionMessages/ActionErrors对象是否存在;
          eg. 如果存在error信息,将其全部输出:
               <logic:messagePresent property=”error”>
                  <html:messages property=”error” id=”errMsg” >
                        <bean:write name=”errMsg”/>
                  </html:messages> 
               </logic:messagePresent >
     13. logic:messagesNotPresent
          该标签用于判断ActionMessages/ActionErrors对象是否不存在,使用方法与logic:messagePresent类似,略
      14. logic:present
           此标签用于判断request对象传递参数是否存在。
           eg1. user对象和它的name属性在request中都存在时,输出相应字符串:
              <logic:present name=”user” property=”name”>
                  user对象和该对象的name属性都存在
            </logic:present>
          eg2. 若有一个名字为“user”的JavaBean,输出对应字符串:
             <logic:present name=”user” >
                  有一个名字为“user”的JavaBean。
            </logic:present>
          eg3.
            <logic:present header=”user-agent”>
                  we got a user-agent header.
            </logic:present>
      15. logic:notPresent
           此标签用于判断request对象传递参数是否不存在,意义与了logic:present相反,使用方法类似,略。
      16. logic:redirect
           该标签用于实现页面转向,可传递参数。
           eg1. <logic:redirect href=”http://www.chinaitlab.com”/>
     
       17. logic:iterator
            用于显示列表为collection的值(List ,ArrayList,HashMap等)。
            eg1. 逐一输出用户列表(userlList)中用户的姓名:
               <logic:iterate  id=”user” name=”userList”>
                  <bean:write name=”user” property=”name”/><br>
               </logic:iterate>
            eg2. 从用户列表中输出从1开始的两个用户的姓名
               <logic:iterate  id=”user” name=”userList” indexId=”index”  offset=”1″ length=”2″>
                  <bean:write name=”index”/>.<bean:write name=”user” property=”name”/><br>
               </logic:iterate>
            eg3. logic:iterator标签的嵌套举例
                <logic:iterate id=”user” indexId=”index” name=”userList”>
                       <bean:write name=”index”/>. <bean:write name=”user” property=”name”/><br>
                       <logic:iterate id=”address” name=”user” property=”addressList” length=”3″ offset=”1″>
                           <bean:write name=”address”/><br>
                       </logic:iterate>
               </logic:iterate>
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
public ActionForward execute(ActionMapping mapping,                                                  ActionForm form,
                                                 HttpServletRequest request,                                                  HttpServletResponse response) {
   ThreeForm threeForm = (ThreeForm) form;
   //OneForm oneForm=(OneForm)form;
   //String str=(String) s.getAttribute(“name”);
   //threeForm.setName(str);  //这样写会造成ClassCastException
   HttpSession session=request.getSession();
   OneForm oneForm=(OneForm)session.getAttribute(“oneForm”);
   threeForm.setName(oneForm.getName());
   return mapping.findForward(“three”);
}

Struct中的命名规则

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

<form   action=”/Logon.do”>  
  改成<html:form   action=”/Logon.do”>  
  原因是你没有办法生成form实例^_^  
  (接分) 

关于structs中的命名规则:
在设置属性名字的时候,名字的开头必须为小写,
且至少开头是两个以上的字母.
例如: bigIcon smallIcon 不能简写成 bIcon sIcon
因为当myeclipse自动生成代码是会变成:setBIcon()/getBIcon()
和setSIcon()/getSIcon(),以这种方式命名的方法,struts是无法
识别的。

Java String字符串讲解

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

节省^_^?
String s=null;//null是未分配堆内存空间
String a;//分配了一个内存空间,没存入任何对象
String a=”";//分配了一个内存空间,存了一个字符串对象

SSL协议分析与实现

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

1引言
       SSL是一种在客户端和服务器端之间建立安全通道的协议。SSL一经提出,就在Internet上得到广泛的应用。SSL最常用来保护Web的安全。为了保护存有敏感信息Web的服务器的安全,消除用户在Internet上数据传输的安全顾虑。
OpenSSL是一个支持SSL认证的服务器.它是一个源码开放的自由软件,支持多种操作系统。OpenSSL软件的目的是实现一个完整的、健壮的、商业级的开放源码工具,通过强大的加密算法来实现建立在传输层之上的安全性。OpenSSL包含一套SSL协议的完整接口,应用程序应用它们可以很方便的建立起安全套接层,进而能够通过网络进行安全的数据传输。
2  SSL协议概述
SSL 是Secure socket Layer英文缩写,它的中文意思是安全套接层协议,指使用公钥和私钥技术组合的安全网络通讯协议。SSL协议是网景公司(Netscape)推出的基于 WEB应用的安全协议,SSL协议指定了一种在应用程序协议(如Http、Telenet、NMTP和FTP等)和TCP/IP协议之间提供数据安全性分层的机制,它为TCP/IP连接提供数据加密、服务器认证、消息完整性以及可选的客户机认证,主要用于提高应用程序之间数据的安全性,对传送的数据进行加密和隐藏,确保数据在传送中不被改变,即确保数据的完整性。
 SSL 以对称密码技术和公开密码技术相结合,可以实现如下三个通信目标:
(1)秘密性: SSL客户机和服务器之间传送的数据都经过了加密处理,网络中的非法窃听者所获取的信息都将是无意义的密文信息。
( 2)完整性: SSL利用密码算法和散列(HASH)函数,通过对传输信息特征值的提取来保证信息的完整性,确保要传输

的信息全部到达目的地,可以避免服务器和客户机之间的信息受到破坏。
(3)认证性:利用证书技术和可信的第三方认证,可以让客户机和服务器相互识别对方的身份。为了验证证书持有者是其合法用户(而不是冒名用户), SSL要求证书持有者在握手时相互交换数字证书,通过验证来保证对方身份的合法性。
3  SSL协议的体系结构
SSL协议位于TCP/IP协议模型的网络层和应用层之间,使用TCP来提供一种可靠的端到端的安全服务,它是客户/服务器应用之间的通信不被攻击窃听,并且始终对服务器进行认证,还可以选择对客户进行认证。SSL协议在应用层通信之前就已经完成加密算法、通信密钥的协商以及服务器认证工作,在此之后,应用层协议所传送的数据都被加密。SSL实际上是共同工作的两层协议组成,如图1所示。从体系结构图可以看出SSL安全协议实际是SSL握手协议、SSL修改密文协议、SSL警告协议和SSL记录协议组成的一个协议族。
 
握手
协议
修改密 
文协议
报警
协议
        SSL记录协议
           TCP
           IP
        
         图1  SSL体系结构
        SSL记录协议为SSL连接提供了两种服务:一是机密性,二是消息完整性。为了实现这两种服务, SSL记录协议对接收的数据和被接收的数据工作过程是如何实现的呢? SSL记录协议接收传输的应用报文,将数据分片成可管理的块,进行数据压缩(可选),应用MAC,接着利用IDEA、DES、3DES或其他加密算法进行数据加密,最后增加由内容类型、主要版本、次要版本和压缩长度组成的首部。被接收的数据刚好与接收数据工作过程相反,依次被解密、验证、解压缩和重新装配,然后交给更高级用户。
        SSL修改密文协议是使用SSL记录协议服务的SSL高层协议的3个特定协议之一,也是其中最简单的一个。协议由单个消息组成,该消息只包含一个值为1的单个字节。该消息的唯一作用就是使未决状态拷贝为当前状态,更新用于当前连接的密码组。为了保障SSL传输过程的安全性,双方应该每隔一段时间改变加密规范。
        SSL告警协议是用来为对等实体传递SSL的相关警告。如果在通信过程中某一方发现任何异常,就需要给对方发送一条警示消息通告。警示消息有两种:一种是 Fatal错误,如传递数据过程中,发现错误的MAC,双方就需要立即中断会话,同时消除自己缓冲区相应的会话记录;第二种是Warning消息,这种情况,通信双方通常都只是记录日志,而对通信过程不造成任何影响。SSL握手协议可以使得服务器和客户能够相互鉴别对方,协商具体的加密算法和MAC算法以及保密密钥,用来保护在SSL记录中发送的数据。
SSL握手协议允许通信实体在交换应用数据之前协商密钥的算法、加密密钥和对客户端进行认证(可选)的协议,为下一步记录协议要使用的密钥信息进行协商,使客户端和服务器建立并保持安全通信的状态信息。SSL握手协议是在任何应用程序数据传输之前使用的。SSL握手协议包含四个阶段:第一个阶段建立安全能力;第二个阶段服务器鉴别和密钥交换;第三个阶段客户鉴别和密钥交换;第四个阶段完成握手协议。
4        SSL协议的实现
基于OpenSSL的程序可以被分为两个部分:客户机和服务器,使用SSL协议使通信双方可以相互验证对方身份的真实性,并且能够保证数据的完整性和机密性。建立SSL通信的过程如图2所示。
   
     图2  SSL通信过程
 
SSL通信模型采用标准的C/S结构,除了在TCP层上进行传输之外,与普通的网络通信协议没有太大的区别,基于OpenSSL的程序都要遵循以下几个步骤:
(1 ) OpenSSL初始化
在使用OpenSSL之前,必须进行相应的协议初始化工作,这可以通过下面的函数实现:
int SSL_library_int(void);
(2 ) 选择会话协议
在利用OpenSSL开始SSL会话之前,需要为客户端和服务器制定本次会话采用的协议,目前能够使用的协议包括TLSv1.0、SSLv2、SSLv3、SSLv2/v3。
需要注意的是,客户端和服务器必须使用相互兼容的协议,否则SSL会话将无法正常进行。
(3 ) 创建会话环境
在OpenSSL中创建的SSL会话环境称为CTX,使用不同的协议会话,其环境也
不一样的。申请SSL会话环境的OpenSSL函数是:
SSL_CTX *SSL_CTX_new(SSL_METHOD * method);
当SSL会话环境申请成功后,还要根据实际的需要设置CTX的属性,通常的设置是指定SSL握手阶段证书的验证方式和加载自己的证书。制定证书验证方式的函数是:
int SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int(*verify_callback),int(X509_STORE_CTX *));
为SSL会话环境加载CA证书的函数是:
SSL_CTX_load_verify_location(SSL_CTX *ctx,const char *Cafile,const char *Capath);
为SSL会话加载用户证书的函数是:
SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,int type);
为SSL会话加载用户私钥的函数是:
SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx,const char* file,int type);
在将证书和私钥加载到SSL会话环境之后,就可以调用下面的函数来验证私钥和证书是否相符:
int SSL_CTX_check_private_key(SSL_CTX *ctx);
(4) 建立SSL套接字
SSL套接字是建立在普通的TCP套接字基础之上,在建立SSL套接字时可以使用下面的一些函数:
SSL *SSl_new(SSL_CTX *ctx);
//申请一个SSL套接字
int SSL_set_fd(SSL *ssl,int fd);)
//绑定读写套接字
int SSL_set_rfd(SSL *ssl,int fd);
//绑定只读套接字
int SSL_set_wfd(SSL *ssl,int fd);
//绑定只写套接字
(5) 完成SSL握手
在成功创建SSL套接字后,客户端应使用函数SSL_connect( )替代传统的函数connect( )来完成握手过程:
int SSL_connect(SSL *ssl);
而对服务器来讲,则应使用函数SSL_ accept ( )替代传统的函数accept ( )来完成握手过程:
int SSL_accept(SSL *ssl);
握手过程完成之后,通常需要询问通信双方的证书信息,以便进行相应的验证,这可以借助于下面的函数来实现:
X509 *SSL_get_peer_certificate(SSL *ssl);
该函数可以从SSL套接字中提取对方的证书信息,这些信息已经被SSL验证过了。
X509_NAME *X509_get_subject_name(X509 *a);
该函数得到证书所用者的名字。
(6) 进行数据传输
当SSL握手完成之后,就可以进行安全的数据传输了,在数据传输阶段,需要使用SSL_read( )和SSL_write( )来替代传统的read( )和write( )函数,来完成对套接字的读写操作:
int SSL_read(SSL *ssl,void *buf,int num);
int SSL_write(SSL *ssl,const void *buf,int num);
(7 ) 结束SSL通信
当客户端和服务器之间的数据通信完成之后,调用下面的函数来释放已经申请的SSL资源:
int SSL_shutdown(SSL *ssl);
//关闭SSL套接字
void SSl_free(SSL *ssl);
 //释放SSL套接字
void SSL_CTX_free(SSL_CTX *ctx); 
//释放SSL会话环境
4  结束语
SSL协议采用数字证书进行双端实体认证,用非对称加密算法进行密钥协商,用对称加密算法将数据加密后进行传输以保证数据的保密性,并且通过计算数字摘要来验证数据在传输过程中是否被篡改和伪造,从而为敏感数据在Internet上的传输提供了一种安全保障手段。
OpenSSL是一个开放源代码的SSL协议的产品实现,它采用C语言作为开发语言,具备了跨系统的性能。调用OpenSSL  的函数就可以实现一个SSL加密的安全数据传输通道,从而保护客户端和服务器之间数据的安全。
 
参考文献
[1]  信息系统安全[M].戴宗坤,罗万伯 北京:电子工业出版社,2002
[2]  计算机网络安全与加密技术[M]. 李海泉,李健.北京:科学出版社,2001
[3]  SSL与TLS Designing and Building Secure Systems.北京:中国电力出版社,2002
[4]  Network Security with Openss1.
Publisher:O’Reilly& Associates.2002
 
[返回顶部↑]

 站内搜索 
 
相关文章
◎无线局域网WLAN测试新观点介绍
◎无线通信设备通用测试方法
◎宽带语音网络测试
◎USB设备的调试与测试技巧
◎利用视图工具查找嵌入式系统的软件问题
◎利用流量监测方法提升无线宽带接入设备的性能
◎嵌入式软件设计中查找缺陷的几个技巧(下)
◎嵌入式软件设计中查找缺陷的几个技巧(上)
◎消息驱动测试平台可以改善测试覆盖率
◎VoIP视频流质量的测量和监控的实例
◎实时嵌入式系统模型校验技术概述
◎基于声学全息术的先进噪声测量系统
◎SDH/SONET网络同步分层结构的时钟符合性测试
◎VoIP的话音质量测量方法
热门文章
◎路由器测试的类型和方法
◎USB设备的调试与测试技巧
◎通信测试技术发展透视
◎GSM网络测试仪器
◎GSM基站在线测试方法
◎嵌入式测试方案及高速测试技术
◎无线通信设备通用测试方法
◎cdma2000网络测试方法
◎WCDMA系统的核心网测试
◎VoIP的话音质量测量方法
◎IP网络的测试方法
◎嵌入式软件设计中查找缺陷的几个技巧(上)
◎宽带语音网络测试
◎嵌入式软件设计中查找缺陷的几个技巧(下)
◎无线局域网WLAN测试新观点介绍
◎SDH/SONET网络同步分层结构的时钟符合性测试
◎VoIP视频流质量的测量和监控的实例
◎一种新型的通用视频会议系统
◎数据网络主干设备选型分析
◎利用流量监测方法提升无线宽带接入设备的性能
◎浅谈集群网测试仪器选择
◎实时嵌入式系统模型校验技术概述
◎消息驱动测试平台可以改善测试覆盖率
◎如何部署数据通信网络策略
◎利用视图工具查找嵌入式系统的软件问题
◎基于声学全息术的先进噪声测量系统
◎私网拨打公网问题-STUN设置

Google提供的广告

  建议使用IE 5.0以上浏览器,800×600以上分辨率,常年法律顾问:商建刚律师  
版权所有  51testing软件测试网  Copyright?51testing.com 2003-2006, 沪ICP备05003035号
意见反馈及技术支持:webmaster@51testing.com   业务联系:service@51testing.com 电话:021-64471599

serialVersionUID的作用

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

serialVersionUID 用来表明类的不同版本间的兼容性

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。

当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID 。

如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,未作更改的类,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

Mina过滤器

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

package com.toplx.mina.bussiness.filter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoFilterAdapter;
import org.apache.mina.common.IoSession;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Input;
import flex.messaging.io.amf.Amf3Output;

public class SerializationFilter extends IoFilterAdapter {
 SerializationContext seri = new SerializationContext();// 序列化输入输出流

 public void messageReceived(NextFilter nextFilter, IoSession session,
   Object message) throws Exception {
  // DeSerialize the message if it’s a MINA ByteBuffer
  if (!(message instanceof ByteBuffer)) {
   nextFilter.messageReceived(session, message);
   return;
  }

  System.out.println(“接收的数据大小是:”+message);
  // Deserialize
  System.out.println(“Amf3Filter.messageReceived=====>接收到数组长度: ”
    + ((ByteBuffer) message).remaining());
  int size = ((ByteBuffer) message).remaining();
  
  byte[] decodeArray = new byte[size];
  synchronized(message){
   ((ByteBuffer) message).get(decodeArray, 0, decodeArray.length);
  }
  
  ByteArrayInputStream byteArray = new ByteArrayInputStream(decodeArray);
  DataInputStream dataInput = new DataInputStream(byteArray);
  Amf3Input amfin = new Amf3Input(seri);
  amfin.setInputStream(dataInput);
  Object decodedMessage = amfin.readObject();

  // Forward message
  nextFilter.messageReceived(session, decodedMessage);
 }

 public void filterWrite(NextFilter nextFilter, IoSession session,
   WriteRequest writeRequest) throws Exception {

  /*
   * 如果该对象不是mina.ByteBuffer对象,则序列化该对象
   */
  Object message = writeRequest.getMessage();
  if (message instanceof ByteBuffer) {
   nextFilter.filterWrite(session, writeRequest);
   return;
  }

  /*
   * 分配一个缓存区,用户存放序列化对象
   */
  Amf3Output amfout = new Amf3Output(seri);
  ByteBuffer buffer = ByteBuffer.allocate(0);
  buffer.setAutoExpand(true);
  ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
  DataOutputStream dataOut = new DataOutputStream(byteOut);
  dataOut.flush();
  amfout.setOutputStream(dataOut);
  amfout.writeObject(message);
  dataOut.flush();

  byte[] array = byteOut.toByteArray();
  byteOut.close();
  dataOut.close();

  System.out.println(“发送的数据长度 array.length ” + array.length);
  System.out.println(“发送的数据长度 buffer.remaining()” + buffer.remaining());
  synchronized (buffer){
   buffer.put(array);
  }
  System.out.println(“发送的数据长度 buffer.remaining()” + buffer.remaining());
  buffer.flip();
  /*
   * 转发信息到下个过滤器
   */
  nextFilter.filterWrite(session, new WriteRequest(buffer, writeRequest
    .getFuture()));
 }

 /**
  * @return an input stream for a ByteBuffer
  */
 protected static InputStream newInputStream(final ByteBuffer buf) {
  return new InputStream() {

   public synchronized int read() throws IOException {
    if (!buf.hasRemaining()) {
     return -1;
    }
    return buf.get();
   }

   public synchronized int read(byte[] bytes, int off, int len)
     throws IOException {
    // Read only what’s left
    len = Math.min(len, buf.remaining());
    buf.get(bytes, off, len);
    return len;
   }
  };
 }

}

奇都社区游戏RoleData数据结构

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

这里服务器端发送的是一个对象Object

角色的所有信息
Object__
        |___RoleData
                   |___RoleInfor (包含用户的出示化信息)

                   |___RoleFashion(包含用户的服饰信息)

        |___FriendList(字符串,需要做拆分)

这里服务器将在同一地图的上的所有玩家的信息(玩家的初始化信息和服饰信息)
封装成一个Object[]对象数组:
Object[]__
          |___
              Object[0]__
                         |___RoleData
                                    |___RoleInfor (包含用户的出示化信息)

                                    |___RoleFashion(包含用户的服饰信息)

          |___
              Object[2]__
                         |___RoleData
                                    |___RoleInfor (包含用户的出示化信息)

                                    |___RoleFashion(包含用户的服饰信息)

          |__Object[3]………..
这里客户端要做的工作将所有的在线好友的roleId组装成
一个字符串,格式如下:
 
  好友1#好友2#好友3#
  1000001#100002#1000003
注释掉的//role_Id,服务器端不会发送,即客户端可以不用
接受该字符串

Mina线程配置问题

中國壹石頭 发表于 2010-4-24 分类 备份文档_txt | 发表评论

peter royal wrote:

>>
>> Yes, I didn’t think about that possibility. But why not have  
>> something like the following:
>>
>>   IoAcceptor acceptor = …;
>>   IoHandlerFactory factory = …;
>>   acceptor.accept(address, factory);
>>
>> where IoHandlerFactory is an interface that has the responsibility  to
>> create IoHandlers. This factory would be used by the acceptor to  
>> create an IoHandler whenever a new session is accepted.
>>
>> This way, both the client-side and server-side IoHandler could  safely
>> use state in instance variables. This seems more consistent  to me.
>
>
> I guess it just depends on what is the more common case. In my  
> experience, I have no problems with everything flowing into a single  
> IoHandler on the server side. So I would want an IoHandlerFactory  that
> just returned the same instance each time. Whichever way it is  
> implemented, I think it would be a valuable contribution to MINA.
> -pete
>
…[show rest of quote]

If the handler is per session there’s no need to pass in the session in
all methods, is it? IMO it would be nicer to have a new interface:

interface SingleSessionIoHandler {
   void sessionOpened();
   void messageReceived(Object message);
   void sessionClosed();
   …
}

implementation of this interface would typically store the session as an
instance variable.

The factory interface would look like:

interface SingleSessionIoHandlerFactory {
   SingleSessionIoHandler create(IoSession session);
}

To achieve this in MINA you could implement a special IoHandler which
delegates to a SingleSessionIoHandler which it gets from the session:

public class SingleSessionIoHandlerDelegate implements IoHandler {
   SingleSessionIoHandlerFactory factory;
   SingleSessionIoHandlerDelegate(SingleSessionIoHandlerFactory factory){
     this.factory = factory;
   }
   void sessionCreated(IoSession session) {
     SingleSessionIoHandler handler = factory.create(session);
     session.setAttribute(“handler”, handler);
   }
   void sessionOpened(IoSession session) {
     SingleSessionIoHandler handler = session.getAttribute(“handler”);
     handler.sessionOpened();
   }
   void messageReceived(IoSession session, Object message) {
     SingleSessionIoHandler handler = session.getAttribute(“handler”);
     handler.messageReceived(message);
   }
   …
}

To create an acceptor you would simply do:

IoAcceptor acceptor = …;
SingleSessionIoHandlerFactory  factory = …;
acceptor.accept(address, new SingleSessionIoHandlerDelegate(factory));

My point is that there’s no need to modify the IoAcceptor interface to
support this kind of behaviour. I see no harm in including something
like this in MINA. Simon, if you have a patch please add it to JIRA and
we’ll consider it.

/Nikals