Apache MINA 2.0 简单应用示例及与Spring的集成

20 篇文章 0 订阅
1 篇文章 0 订阅
我顶 字号:
Apache MINA 2.0 简单应用示例及与Spring的集成

基于Apache MINA 的网络应用有三个层次,分别是 I/O 服务、I/O 过滤器和 I/O 处理器:
1. I/O 服务:I/O 服务用来执行实际的 I/O 操作。Apache MINA 2.0 已经提供了一系列支持不同协议的 I/O 服务,如 TCP/IP、UDP/IP、串口和虚拟机内部的管道等。我们也可以实现自己的 I/O 服务。
2. I/O 过滤器:I/O 服务能够传输的是字节流,而上层应用需要的是特定的对象与数据结构。I/O 过滤器用来完成这两者之间的转换。I/O 过滤器的另外一个重要作用是对输入输出的数据进行处理,满足横切的需求。多个 I/O 过滤器串联起来,形成 I/O 过滤器链。
3. I/O 处理器:I/O 处理器用来执行具体的业务逻辑, 对接收到的消息执行特定的处理。

应用示例中要实现I/O 处理器及I/O 服务。

开发环境: Windows 7, Apache MINA 2.0.4, eclipse

A. 实现I/O 处理器
I/O 处理器需要实现 org.apache.mina.core.service.IoHandler接口或者继承自org.apache.mina.core.service.IoHandlerAdapter。我们这里选择后者,代码如下:

package mina204.ioBusinessHandler;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CalculatorHandler extends IoHandlerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(CalculatorHandler.class);

private ScriptEngine jsEngine = null;

public CalculatorHandler()
{
ScriptEngineManager seManager = new ScriptEngineManager();
jsEngine = seManager.getEngineByName("JavaScript");

if (jsEngine == null)
{
throw new RuntimeException("Can not find out the javascript engine.");
}
}

public void exceptionCaught(IoSession session, Throwable cause) throws Exception
{
LOG.warn(cause.getMessage(), cause);
}

public void messageReceived(IoSession session, Object message) throws Exception
{
String expression = message.toString();
if ("exit".equalsIgnoreCase(expression.trim()) || "quit".equalsIgnoreCase(expression.trim()))
{
session.close(true);
return;
}
try
{
Object result = jsEngine.eval(expression);
session.write(result.toString());
}
catch (ScriptException e)
{
LOG.error(e.getMessage(), e);
session.write("Error script expression! Please check it again.");
}
}
}


B. 实现I/O 服务:在示例中使用 TCP/IP 协议,需要在指定端口(端口号9876)监听,接受客户端的连接。代码如下:

package mina204.ioServer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import mina204.ioBusinessHandler.CalculatorHandler;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CalculatorServer {
private static final int PORT = 9876;

private static Logger log = LoggerFactory.getLogger(CalculatorServer.class);

public static void main(String args[]) throws IOException {
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec2012", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));

acceptor.setHandler(new CalculatorHandler());
acceptor.bind(new InetSocketAddress(PORT));

log.info("Calculator server has started up.... port: " + PORT);
}
}

说明:
过滤器只有在添加到过滤器链中的时候才起作用。过滤器链是过滤器的容器。过滤器链与 I/O 会话是一一对应的关系。org.apache.mina.core.filterchain.IoFilterChain是 Apache MINA 中过滤器链的接口,其中提供了一系列方法对其中包含的过滤器进行操作,包括查询、添加、删除和替换等。

I/O 事件通过过滤器链之后会到达 I/O 处理器。I/O 处理器中与 I/O 事件对应的方法会被调用。Apache MINA 中 org.apache.mina.core.service.IoHandler是 I/O 处理器要实现的接口,一般情况下,只需要继承自 org.apache.mina.core.service.IoHandlerAdapter并覆写所需方法即可。

运行步骤:
1. 启动 CalculatorServer.
Calculator server has started up.... port: 9876
2. Window 7系统中: 控制面板-->程序-->打开或关闭Windows功能-->勾上"Telnet客户端".
3. 开始-->输入 cmd 打开 system32\cmd.exe -->输入 "telnet localhost 9876"即可测试.

Apache MINA与Spring的集成
配置文件spring-mina.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="calculatorHandler" class="mina204.ioBusinessHandler.CalculatorHandler" />
<bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter" />
<bean id="calculatorCodecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">
<constructor-arg>
<bean class="org.apache.mina.filter.codec.textline.TextLineCodecFactory" />
</constructor-arg>
</bean>
<bean id="filterChainBuilder"
class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
<property name="filters">
<map>
<entry key="loggingFilter" value-ref="loggingFilter" />
<entry key="codecFilter" value-ref="calculatorCodecFilter" />
</map>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.net.SocketAddress">
<bean class="org.apache.mina.integration.beans.InetSocketAddressEditor"/>
</entry>
</map>
</property>
</bean>
<bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"
init-method="bind" destroy-method="unbind">
<property name="defaultLocalAddress" value="127.0.0.1:9876" />
<property name="handler" ref="calculatorHandler" />
<property name="filterChainBuilder" ref="filterChainBuilder" />
</bean>
</beans>

新建I/O Server类: CalculatorServerWithSpringMINA.java 内容如下:

package mina204.ioServer;

import org.apache.mina.core.service.IoAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CalculatorServerWithSpringMINA {
private static Logger log = LoggerFactory.getLogger(CalculatorServerWithSpringMINA.class);

public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring-mina.xml");
IoAcceptor acceptor = (IoAcceptor) ctx.getBean("ioAcceptor");
log.info("Calculator server has started up.... Local Address: "
+ acceptor.getLocalAddress().toString()
+ " Default Local Address: "
+ acceptor.getDefaultLocalAddress().toString());
}

}

同样的测试步骤可以得到预期的结果。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值