自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺談Java的Mina框架傳遞對象

開發(fā) 后端
本篇文章主要講解Java的Mina框架傳遞對象是什么,并附于代碼和圖片方便大家理解。

接觸java的Mina框架已經(jīng)有很多時間了,在網(wǎng)上也讀過了很多的相關(guān)文章,發(fā)現(xiàn)Mina框架的確是一個值得拿來好好研究的東西,前些日子寫了一個山寨QQ項目,其中的通信部分用到了java中自帶的InputStream,OutputStream,Writer,Reader等等,感覺其中的很大的一個問題就是難以將事務(wù)處理的邏輯層與解析層分離開來,造成整個項目看起來比較臃腫,繁瑣,不夠模塊化,接觸Mina后發(fā)現(xiàn)mina在這方面做的很是恰到好處。

看到文章標(biāo)題,你或許會有一些疑惑:

1、Mina框架傳遞對象是怎么回事

2、Mina傳遞對象可以用來做什么

3、Mina傳遞對象是怎么進(jìn)行的

4、Mina傳遞對象過程中會遇到什么問題呢

在用原來的java的InputStream,OutputStream,Writer,Reader等進(jìn)行通信的時候我們會將信息編碼轉(zhuǎn)化成字節(jié)流等進(jìn)行信息傳遞,InputStream,OutputStream是基于字節(jié)流的,而Writer,Reader是基于字符的,我們都知道進(jìn)行通信的服務(wù)器和客戶端是事先必須定好通信協(xié)議,如果我們將你好嗎?定義為是一條消息,視頻定義為一條視頻請求,如果客戶端將這條消息和請求發(fā)送給了服務(wù)器,服務(wù)器要想得到消息和請求的真正內(nèi)容(在這里分別是“你好嗎?”和“視頻”)并進(jìn)行處理和應(yīng)答就必須進(jìn)行信息的解析,就要一條一條的進(jìn)行判斷:1、如果是信息是……格式的就將其看做是一條消息;2、如果是……格式的就將其看作是一條請求;3、如果是其他形式就將其視為無效信息,不予處理。當(dāng)然這不失為一種辦法可以進(jìn)行信息的提取,但是我們會發(fā)現(xiàn)在這個過程中信息的發(fā)送、接受、解析、處理、應(yīng)答等都是一條一條的,很是零散,比較難以統(tǒng)一,沒有實現(xiàn)消息定義和解析處理過程的分離,這樣寫好了一個程序,如果日后想要進(jìn)行改正其中的一條信息格式,就要在整個項目中Ctrl+F了,比較繁瑣,還容易出錯。

這是我們會自然的想到要用一種東西將各個格式的信息進(jìn)行分類統(tǒng)一起來并方便進(jìn)行一些必要的信息處理,為符合這些特點,我們會想到類這個東東恰恰滿足了這些性質(zhì),我們可以將信息的格式中的內(nèi)容定義為類的屬性,而對這些屬性的處理就可以用類中的方法來予以解決,這樣就對信息進(jìn)行了很好的包裝。

這種思想有了,那就是在通信的時候直接進(jìn)行形式上的對象傳遞(實際上在通信的時候都是最終以字節(jié)流的方式進(jìn)行傳遞的),那么我們就要找一種工具進(jìn)行這種形式的信息傳遞,對了,這種工具就是Mina框架,我們只看他其中的一個方法

public void messageReceived(IoSession session, Object message),這是進(jìn)行消息接收是能夠被 觸發(fā)的一個方法,參數(shù)session代表當(dāng)前的會話對象,參數(shù)message代表接收的到的信息,這時您會發(fā)現(xiàn)message的類型是Object型,而類 Object 是類層次結(jié)構(gòu)的根類,當(dāng)然可以用對象型的作為message啦!前面提到通信的時候都是最終以字節(jié)流的方式進(jìn)行傳遞的,這樣就要進(jìn)行:對象(客戶端)->字節(jié)流(客戶端)->發(fā)送->接收->字節(jié)流(服務(wù)器)->對象(服務(wù)器)的過程,呵呵不用擔(dān)心,這些繁瑣的過程,Mina都提供了很好的底層默認(rèn)實現(xiàn)所以你只需稍稍敲點代碼就行了。

光說不練還是不行,先上一個程序?qū)嵗?/P>

服務(wù)器端(1):

Java代碼

 

 

  1. package Mina.server;     
  2.     
  3. import java.io.IOException;     
  4. import java.net.InetSocketAddress;     
  5.     
  6. import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;     
  7. import org.apache.mina.filter.codec.ProtocolCodecFilter;     
  8. import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;     
  9. import org.apache.mina.transport.socket.SocketAcceptor;     
  10. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;     
  11.     
  12. public class MainServer {     
  13.     private static MainServer mainServer = null;     
  14.     private SocketAcceptor acceptor = new NioSocketAcceptor();     
  15.     private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();     
  16.     private int bindPort = 8888;     
  17.     
  18.     public static MainServer getInstances() {     
  19.         if (null == mainServer) {     
  20.             mainServer = new MainServer();     
  21.         }     
  22.         return mainServer;     
  23.     }     
  24.     
  25.     private MainServer() {     
  26.         chain.addLast("myChin"new ProtocolCodecFilter(     
  27.                 new ObjectSerializationCodecFactory()));     
  28.         acceptor.setHandler(ServerHandler.getInstances());     
  29.         try {     
  30.             acceptor.bind(new InetSocketAddress(bindPort));     
  31.         } catch (IOException e) {     
  32.             e.printStackTrace();     
  33.         }     
  34.     }     
  35.     
  36.     public static void main(String[] args) throws Exception {     
  37.         MainServer.getInstances();     
  38.     }     
  39. }    

 

服務(wù)器端(2):

Java代碼

 

 

  1. package Mina.server;     
  2.     
  3. import org.apache.mina.core.filterchain.IoFilterAdapter;     
  4. import org.apache.mina.core.service.IoHandler;     
  5. import org.apache.mina.core.session.IdleStatus;     
  6. import org.apache.mina.core.session.IoSession;     
  7.     
  8. import Mina.Object.UserInfo;     
  9.     
  10. public class ServerHandler extends IoFilterAdapter implements IoHandler {     
  11.     private static ServerHandler samplMinaServerHandler = null;     
  12.     
  13.     public static ServerHandler getInstances() {     
  14.         if (null == samplMinaServerHandler) {     
  15.             samplMinaServerHandler = new ServerHandler();     
  16.         }     
  17.         return samplMinaServerHandler;     
  18.     }     
  19.     
  20.     private ServerHandler() {     
  21.     
  22.     }     
  23.     
  24.     // 當(dāng)連接后打開時觸發(fā)此方法,一般此方法與 sessionCreated 會被同時觸發(fā)     
  25.     public void sessionOpened(IoSession session) throws Exception {     
  26.     }     
  27.     public void sessionClosed(IoSession session) {     
  28.     }     
  29.     public void messageReceived(IoSession session, Object message)     
  30.             throws Exception {       
  31.         if (message instanceof UserInfo) {     
  32.             UserInfo text = (UserInfo) message;     
  33.             System.out.println("服務(wù)器接收到從客戶端的姓名:"+text.getName());     
  34.             System.out.println("服務(wù)器接收到從客戶端的QQ:"+text.getQQNum());     
  35.         }      
  36.     }     
  37.     
  38.     public void exceptionCaught(IoSession arg0, Throwable arg1)     
  39.             throws Exception {     
  40.     
  41.     }     
  42.     
  43.     // 當(dāng)消息傳送到客戶端后觸發(fā)     
  44.     public void messageSent(IoSession arg0, Object arg1) throws Exception {     
  45.              
  46.     }     
  47.     
  48.     // 當(dāng)一個新客戶端連接后觸發(fā)此方法.     
  49.     public void sessionCreated(IoSession arg0) throws Exception {     
  50.              
  51.     }     
  52.     
  53.     // 當(dāng)連接空閑時觸發(fā)此方法.     
  54.     public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {     
  55.              
  56.     }     
  57.     
  58. }    

 

客戶端(1):

Java代碼

 

 

  1. package Mina.client;     
  2.     
  3. import java.net.InetSocketAddress;     
  4.     
  5. import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;     
  6. import org.apache.mina.core.future.ConnectFuture;     
  7. import org.apache.mina.filter.codec.ProtocolCodecFilter;     
  8. import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;     
  9. import org.apache.mina.transport.socket.nio.NioSocketConnector;     
  10.     
  11. public class MainClient {     
  12.     private static MainClient mainClient = null;     
  13.     NioSocketConnector connector = new NioSocketConnector();     
  14.     DefaultIoFilterChainBuilder chain = connector.getFilterChain();     
  15.     
  16.     public static MainClient getInstances() {     
  17.         if (null == mainClient) {     
  18.             mainClient = new MainClient();     
  19.         }     
  20.         return mainClient;     
  21.     }     
  22.     
  23.     private MainClient() {     
  24.         chain.addLast("myChin"new ProtocolCodecFilter(     
  25.                 new ObjectSerializationCodecFactory()));     
  26.         connector.setHandler(ClientHandler.getInstances());     
  27.         connector.setConnectTimeout(30);     
  28.         ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",     
  29.                 8888));     
  30.     }     
  31.     
  32.     public static void main(String args[]) {     
  33.         MainClient.getInstances();     
  34.     }     
  35. }  

 

客戶端(2):

Java代碼

復(fù)制代碼

 

 

  1. package Mina.client;     
  2.     
  3. import org.apache.mina.core.service.IoHandlerAdapter;     
  4. import org.apache.mina.core.session.IoSession;     
  5.     
  6. import Mina.Object.UserInfo;     
  7.     
  8. public class ClientHandler extends IoHandlerAdapter {     
  9.     private static ClientHandler samplMinaClientHandler = null;     
  10.     public static ClientHandler getInstances() {     
  11.         if (null == samplMinaClientHandler) {     
  12.             samplMinaClientHandler = new ClientHandler();     
  13.         }     
  14.         return samplMinaClientHandler;     
  15.     }     
  16.     
  17.     private ClientHandler() {     
  18.     
  19.     }     
  20.     
  21.     public void sessionOpened(IoSession session) throws Exception {     
  22.         session.write("客戶端與服務(wù)器的會話打開了……");     
  23.         UserInfo text=new UserInfo();     
  24.         text.setName("梅竹寒香");     
  25.         text.setQQNum("972341215");     
  26.         session.write(text);     
  27.     }     
  28.     
  29.     public void sessionClosed(IoSession session) {     
  30.     }     
  31.     
  32.     public void messageReceived(IoSession session, Object message)     
  33.             throws Exception {     
  34.     }     
  35.     
  36.     public void messageSent(IoSession arg0, Object arg1) throws Exception {     
  37.         System.out.println("客戶端已經(jīng)向服務(wù)器發(fā)送了:"+(String)arg1);     
  38.     }     
  39. }    

 

公共類:

Java代碼

復(fù)制代碼

 

 

  1. package Mina.Object;     
  2.     
  3. public class UserInfo implements java.io.Serializable{     
  4.     private String name;     
  5.     private String QQNum;     
  6.     public String getName() {     
  7.         return name;     
  8.     }     
  9.     public void setName(String name) {     
  10.         this.name = name;     
  11.     }     
  12.     public String getQQNum() {     
  13.         return QQNum;     
  14.     }     
  15.     public void setQQNum(String qQNum) {     
  16.         QQNum = qQNum;     
  17.     }     
  18.          
  19.          
  20. }    

 

如下建包即可:

 

 

以上就是對象的收發(fā)的簡單示例,如果報錯,或許會是一下原因:1、包的引進(jìn)是否妥當(dāng) 2、是否引入了mina的第三方包(網(wǎng)上有了很多的相關(guān)文章,在此就不在贅述了)

通過程序您會看到對象已經(jīng)成功傳遞并進(jìn)行了相關(guān)屬性的輸出,對于這個簡單的程序我稍做些相關(guān)說明:

1、進(jìn)行傳遞的對象所實例化的類要實現(xiàn)java.io.Serializable序列化接口

2、您會發(fā)現(xiàn)實例中的類尤其是相關(guān)的IoHandlerAdapter繼承類都采用了單實例模式,為什么這樣做呢,原因很簡單,那就是要在整個通信過程中做到對象session的等實例的單一防止發(fā)生“所托非人”的現(xiàn)象

3、服務(wù)器接收到message在進(jìn)行類判斷時用了instanceof關(guān)鍵字

如果你看到上面的實例就覺得對象傳遞的學(xué)習(xí)已經(jīng)成功了,那就錯了,細(xì)心的博友看到這個包結(jié)構(gòu):

 

 

是不是有點問題呢。

例如客戶端傳了一個userinfo對象到服務(wù)器,在服務(wù)器端判斷如果是userinfo對象后就打印出相關(guān)信息,我看源碼文檔其中有這樣的建包方式

 

 

其中服務(wù)器和客戶端共用了中間的Mina.Object包,這樣在收到對象后就能通過instanceof關(guān)鍵字判斷是不是useinfo對象,我看了一下,這個方法是可行的,現(xiàn)在的問題是,我們?nèi)绻帉懲ㄓ嵻浖臅r候,肯定是服務(wù)器和客戶端是要分開的,所以那個Mina.Object包是不能共享的,所以問題來了(1)、如果將userinfo放到客戶端中,那么該怎么用instanceof進(jìn)行判斷是不是userinfo呢(這時你已經(jīng)不能再引入服務(wù)器中的userinfo了)(2)、如果在客戶端和服務(wù)器中都編寫一個類定義一樣的userinfo,可是他們這兩個類是分屬不同的包,所以是兩個不同的類了,這樣在用instanceof進(jìn)行判斷的時候也是行不通的;那么我們該用什么方法來進(jìn)行判斷接收到的類是不是userinfo對象呢?

這個問題把我糾結(jié)了很久,在網(wǎng)上面搜了好久也沒有解決,最后想了想那個(2)或許可以改動改動就可以解決,問題的關(guān)鍵在于兩個UserInfo分屬于兩個不同的包,如果可以將包名一致就好了,但是在一個工程里面不能同時建立兩個命名一樣的包,這樣你就會發(fā)現(xiàn)何不建立兩個工程呢一個是服務(wù)器,一個是客戶端,這樣都可以分別建立名字都是Object的包,這樣可不可行呢,經(jīng)過試驗果然可以,這樣就就解決了上面的問題工程圖如下

 

 

好啦,有了這個工具,您會有什么想法呢?對象傳遞還可以做什么?那就是可以用它來進(jìn)行圖片,文件的傳遞啦,這個只是個小小的提示具體怎么實現(xiàn),就要看各位博友怎么發(fā)揮啦!呵呵

【編輯推薦】

  1. 巧解使Eclipse崩潰的JVM terminated問題
  2. 解析Mina代碼三部曲
  3. Java編譯過程與c/c++編譯過程有何不同
  4. 淺談jvm.dll裝載過程與源代碼分析
  5. Java虛擬機(jī)(JVM)中的內(nèi)存設(shè)置詳解
責(zé)任編輯:金賀 來源: JavaEye博客
相關(guān)推薦

2012-05-03 10:55:51

ApacheMINAJava

2017-08-04 11:41:53

Javathreadpool框架

2017-08-07 20:50:27

JavaForkJoin

2009-09-04 11:00:13

通過C#引用傳遞

2009-09-22 17:38:25

Jobs框架

2011-06-28 09:51:08

.NET對象相等

2009-09-07 03:23:40

C# Main方法

2009-09-29 10:46:58

Hibernate領(lǐng)域

2009-05-12 09:54:09

JavaRestCoC

2009-06-29 17:17:57

Spring

2009-04-24 09:43:09

.NETASP.NET框架

2011-08-31 13:27:52

AndroidPhoneGap

2011-07-08 17:57:37

iPhone CoreData 數(shù)據(jù)庫

2009-08-12 11:24:25

C# String對象

2009-08-19 17:12:18

C# Connecti

2009-08-31 09:37:09

C# Employee

2009-09-02 15:41:21

C# HTTPWebR

2009-09-14 13:30:04

Linq數(shù)據(jù)和對象

2011-09-07 16:57:31

QT WidgetQWidget

2009-06-04 09:11:34

學(xué)習(xí)strutsstruts框架
點贊
收藏

51CTO技術(shù)棧公眾號