Apache MINA是一個網絡應用程序框架,它可以幫助用戶開發的高性能、高擴展性的網絡應用程序。它提供了一個抽象的事件驅動的異步API在不同傳輸如TCP/IP和UDP/IP通過java NIO。
Apache MINA通常被稱為:
NIO框架庫,
客戶端服務器框架庫,或
一個網絡socket庫
code案例:
test.properties 配置文件
1 #mina2.0 2 mina.server.serverLocationAddress = 127.0.0.1:9998
applicationContext.xml 配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 6 "> 7 8 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 9 <property name="locations"> 10 <value>classpath:propertiesConfig/test.properties</value> 11 </property> 12 </bean> 13 <!-- 定義數據處理Bean --> 14 <bean id="serverHandler" class="com.maven.project.web.mina2.ServerHandler" /> 15 16 <!-- executorFilter多線程處理 --> 17 <bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" /> 18 19 <bean id="mdcInjectionFilter" class="org.apache.mina.filter.logging.MdcInjectionFilter"> 20 <constructor-arg value="remoteAddress" /> 21 </bean> 22 23 <!-- 字符編 碼過濾器 --> 24 <bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter"> 25 <constructor-arg> 26 <!-- <bean class="org.apache.mina.filter.codec.textline.TextLineCodecFactory" />--> 27 <!-- 處理對象流時候用ObjectSerializationCodecFactory --> 28 <!-- <bean class="org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory" /> --> 29 <bean class="com.maven.project.web.mina2.ServerCodeFactory" /> 30 </constructor-arg> 31 </bean> 32 33 <!-- 日志過濾器 --> 34 <bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter" /> 35 36 <!-- 過濾器鏈 --> 37 <bean id="filterChainBuilder" class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder"> 38 <property name="filters"> 39 <map> 40 <entry key="executor" value-ref="executorFilter" /> 41 <entry key="mdcInjectionFilter" value-ref="mdcInjectionFilter" /> 42 <entry key="codecFilter" value-ref="codecFilter" /> 43 <entry key="loggingFilter" value-ref="loggingFilter" /> 44 </map> 45 </property> 46 </bean> 47 48 <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> 49 <property name="customEditors"> 50 <map> 51 <entry key="java.net.SocketAddress" value="org.apache.mina.integration.beans.InetSocketAddressEditor"/> 52 </map> 53 </property> 54 </bean> 55 56 <!-- session config 通過工廠方法注入 --> 57 <bean id="sessionConfig" factory-bean="ioAcceptor" factory-method="getSessionConfig" > 58 <property name="bothIdleTime" value="180"/><!-- 配置session 空閒時間,單位 秒 --> 59 </bean> 60 61 <bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor" init-method="bind" destroy-method="unbind"> 62 <property name="defaultLocalAddress" value="${mina.server.serverLocationAddress}" /> 63 <property name="handler" ref="serverHandler" /> 64 <property name="filterChainBuilder" ref="filterChainBuilder" /> 65 <property name="reuseAddress" value="true" /> 66 </bean> 67 </beans>
maven pom.xml 配置文件
1 <properties> 2 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 3 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 4 <mina-version>2.0.13</mina-version> 5 <mina-groupId>org.apache.mina</mina-groupId> 6 </properties> 7 <!-- mina --> 8 <dependency> 9 <groupId>${mina-groupId}</groupId> 10 <artifactId>mina-core</artifactId> 11 <version>${mina-version}</version> 12 </dependency> 13 <dependency> 14 <groupId>${mina-groupId}</groupId> 15 <artifactId>mina-integration-beans</artifactId> 16 <version>${mina-version}</version> 17 </dependency>
handler 業務處理類
1 package com.maven.project.web.mina2; 2 3 import org.apache.mina.core.service.IoHandlerAdapter; 4 import org.apache.mina.core.session.IdleStatus; 5 import org.apache.mina.core.session.IoSession; 6 7 public class ServerHandler extends IoHandlerAdapter { 8 9 /**當一個新客戶端連接後觸發此方法*/ 10 @Override 11 public void sessionCreated(IoSession session) throws Exception { 12 System.out.println("===============sessionCreated============="); 13 } 14 15 /**當連接後打開時觸發此方法,一般此方法與 sessionCreated 會被同時觸發*/ 16 @Override 17 public void sessionOpened(IoSession session) throws Exception { 18 System.out.println("===============sessionOpened============="); 19 } 20 21 /**當連接被關閉時觸發,例如客戶端程序意外退出等等*/ 22 @Override 23 public void sessionClosed(IoSession session) throws Exception { 24 System.out.println("===============sessionClosed============="); 25 if(null != session){ 26 session.closeOnFlush(); 27 } 28 } 29 30 /**當連接空閒時觸發此方法*/ 31 @Override 32 public void sessionIdle(IoSession session, IdleStatus status) throws Exception { 33 System.out.println("===============sessionIdle============="); 34 this.sessionClosed(session); 35 } 36 37 /**當接口中其他方法拋出異常未被捕獲時觸發此方法*/ 38 @Override 39 public void exceptionCaught(IoSession session, Throwable cause) throws Exception { 40 System.out.println("===============exceptionCaught============="); 41 this.sessionClosed(session); 42 } 43 44 /**當接收到客戶端的請求信息後觸發此方法*/ 45 @Override 46 public void messageReceived(IoSession session, Object message) throws Exception { 47 System.out.println("===============messageReceived============="+message); 48 } 49 50 /**當信息已經傳送給客戶端後觸發此方法*/ 51 @Override 52 public void messageSent(IoSession session, Object message) throws Exception { 53 System.out.println("===============messageSent============="); 54 } 55 56 @Override 57 public void inputClosed(IoSession session) throws Exception { 58 System.out.println("===============inputClosed============="); 59 this.sessionClosed(session); 60 } 61 62 }
encode 類
1 package com.maven.project.web.mina2; 2 3 import java.nio.charset.Charset; 4 5 import org.apache.mina.core.buffer.IoBuffer; 6 import org.apache.mina.core.session.IoSession; 7 import org.apache.mina.filter.codec.ProtocolEncoder; 8 import org.apache.mina.filter.codec.ProtocolEncoderOutput; 9 10 public class ServerEnCoder implements ProtocolEncoder { 11 12 private Charset charset = null; 13 14 public ServerEnCoder(Charset charset) { 15 this.charset = charset; 16 } 17 18 @Override 19 public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { 20 IoBuffer buf = IoBuffer.allocate(message.toString().getBytes().length).setAutoExpand(true); 21 buf.putString(message.toString(), charset.newEncoder()); 22 buf.flip(); 23 out.write(buf); 24 return; 25 } 26 27 @Override 28 public void dispose(IoSession session) throws Exception { } 29 30 }
decode 類
1 package com.maven.project.web.mina2; 2 3 import java.nio.charset.Charset; 4 5 import org.apache.mina.core.buffer.IoBuffer; 6 import org.apache.mina.core.session.IoSession; 7 import org.apache.mina.filter.codec.CumulativeProtocolDecoder; 8 import org.apache.mina.filter.codec.ProtocolDecoderOutput; 9 10 public class ServerDecoder extends CumulativeProtocolDecoder { 11 12 private static final int HANDLENGTH = 4; 13 14 private Charset charset = null; 15 16 public ServerDecoder(Charset charset) { 17 this.charset = charset; 18 } 19 20 @Override 21 protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { 22 if (in.remaining() < HANDLENGTH) { 23 return false; 24 } 25 byte[] sizeBytes = new byte[HANDLENGTH]; 26 in.mark();// 標記當前位置,以便reset 27 in.get(sizeBytes, 0, HANDLENGTH);// 讀取4字節 28 int size = Integer.parseInt(new String(sizeBytes, this.charset)); 29 in.reset(); 30 if (size > in.remaining()) {// 如果消息內容不夠,則重置,相當於不讀取size 31 return false;// 父類接收新數據,以拼湊成完整數據 32 } else { 33 byte[] bytes = new byte[size]; 34 in.get(bytes, 0, size); 35 out.write(new String(bytes, this.charset)); 36 if (in.remaining() > 0) {// 如果讀取內容後還粘了包,就讓父類再重讀 一次,進行下一次解析 37 return true; 38 } 39 } 40 return false;// 處理成功,讓父類進行接收下個包 41 } 42 }
編碼過濾工廠
1 package com.maven.project.web.mina2; 2 3 import java.nio.charset.Charset; 4 5 import org.apache.mina.core.session.IoSession; 6 import org.apache.mina.filter.codec.ProtocolCodecFactory; 7 import org.apache.mina.filter.codec.ProtocolDecoder; 8 import org.apache.mina.filter.codec.ProtocolEncoder; 9 10 public class ServerCodeFactory implements ProtocolCodecFactory { 11 12 private ServerEnCoder encoder; 13 14 private ServerDecoder decoder; 15 16 public ServerCodeFactory(){ 17 this(Charset.defaultCharset().name()); 18 } 19 20 public ServerCodeFactory(String charsetName){ 21 encoder = new ServerEnCoder(Charset.forName(charsetName)); 22 decoder = new ServerDecoder(Charset.forName(charsetName)); 23 } 24 25 @Override 26 public ProtocolEncoder getEncoder(IoSession session) throws Exception { 27 return encoder; 28 } 29 30 @Override 31 public ProtocolDecoder getDecoder(IoSession session) throws Exception { 32 return decoder; 33 } 34 35 }