码迷,mamicode.com
首页 > 编程语言 > 详细

Mina与Spring整合

时间:2016-01-13 10:43:04      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:

首先需要导入的包

技术分享

applicationContext-mina.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-2.5.xsd">
  6.     <!-- 配置地址 -->
  7.     <bean class="com.sharp.slc.net.common.EncryptPropertyPlaceholderConfigurer">  
  8.       <property name="order" value="1"/>  
  9.       <property name="ignoreUnresolvablePlaceholders" value="true"/>  
  10.       <property name="locations">  
  11.         <list>  
  12.             <value>classpath:ssl.properties</value>  
  13.         </list>  
  14.       </property>  
  15.     </bean>
  16.     <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  17.         <property name="customEditors">
  18.             <map>
  19.                 <!-- spring升级后此配置已失效 会报错 -->
  20.                 <!-- <entry key="java.net.SocketAddress"> -->
  21.                 <!-- <bean class="org.apache.mina.integration.beans.InetSocketAddressEditor"
  22.                     /> -->
  23.                 <!-- </entry> -->
  24.                 <!-- 修改这里 -->
  25.                 <entry key="java.net.SocketAddress"
  26.                     value="org.apache.mina.integration.beans.InetSocketAddressEditor">
  27.                 </entry>
  28.             </map>
  29.         </property>
  30.     </bean>
  31.     <!-- 配置业务处理类 -->
  32.     <bean id="serviceHandler" class="com.sharp.slc.net.core.TCPServerHandler" />
  33.     <!-- 配置service -->
  34.     <bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"
  35.         init-method="bind" destroy-method="unbind">
  36.         <property name="defaultLocalAddress" value=":2001" />
  37.         <property name="handler" ref="serviceHandler" />
  38.         <property name="filterChainBuilder" ref="filterChainBuilder" />
  39.     </bean>
  40.     <!-- 配置解码器 -->
  41.     <bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">
  42.         <constructor-arg>
  43.             <bean class="com.sharp.slc.net.core.codec.TextCodecFactory" />
  44.             
  45. <!--     <bean class="org.apache.mina.filter.codec.textline.TextLineCodecFactory" /> -->
  46.         </constructor-arg>
  47.     </bean>
  48.     <!-- 配置日志拦截器 -->
  49.     <bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter" />
  50.     <!-- 配置SSL拦截器 -->
  51.     <bean id="sslFilter" class="org.apache.mina.filter.ssl.SslFilter">
  52.         <constructor-arg ref="sslContext" />
  53. <!--         <property name="needClientAuth" value="true" /> -->
  54.     </bean>
  55.     <!-- The SSL configuration -->
  56.     <bean id="keystoreFactory" class="org.apache.mina.filter.ssl.KeyStoreFactory">
  57.         <property name="password">
  58.             <value>${key_password}</value>
  59.         </property>
  60.     <!--     <property name="dataUrl" value="file:/d:/certs/server.jks" />  -->
  61.         <property name="dataUrl" value="file:/usr/local/tomcat8/certs/server.jks" />
  62.     </bean>
  63.     <bean id="keyStore" factory-bean="keystoreFactory" factory-method="newInstance" />
  64.     <!-- SSLContext to be used -->
  65.     <bean id="sslContextFactory" class="org.apache.mina.filter.ssl.SslContextFactory">
  66.         <property name="protocol" value="TLSV1.2" />
  67.         <property name="keyManagerFactoryAlgorithm" value="SunX509" />
  68.         <property name="keyManagerFactoryKeyStore">
  69.             <ref local="keyStore" />
  70.         </property>
  71.         <property name="keyManagerFactoryKeyStorePassword">
  72.             <value>${keyManager_password}</value>
  73.         </property>
  74.     </bean>
  75.     <bean id="sslContext" factory-bean="sslContextFactory"
  76.         factory-method="newInstance" />
  77.     <!-- 将日志和解码器添加 -->
  78.     <bean id="filterChainBuilder"
  79.         class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
  80.         <property name="filters">
  81.             <map>
  82.                 <entry key="sslFilter" value-ref="sslFilter" />
  83.                 <entry key="loggingFilter" value-ref="loggingFilter" />
  84.                 <entry key="codecFilter" value-ref="codecFilter" />
  85.             </map>
  86.         </property>
  87.     </bean>
  88. </beans>

SessionCache.java

  1. public class SessionCache {
  2.     private final static Log log = LogFactory.getLog(SessionCache.class);
  3.     private static SessionCache session = null;
  4.     /** 设备连接信息[sessions] */
  5.     private Map<String, IoSession> sessions = new HashMap<String, IoSession>();
  6.     private static final String value = KVStoreConfig.getIpAddress();
  7.     /**
  8.      * 获取唯一实例
  9.      */
  10.     public static SessionCache getInstance() {
  11.         log.debug(" <<< Session单例获取 <<< ");
  12.         if (session == null) {
  13.             session = new SessionCache();
  14.         }
  15.         return session;
  16.     }
  17.     /**
  18.      * 获取设备连接信息[sessions]
  19.      *
  20.      * @return 设备连接信息[sessions]
  21.      */
  22.     public Map<String, IoSession> getSessions() {
  23.         return sessions;
  24.     }
  25.     /**
  26.      * 设置设备连接信息[sessions]
  27.      *
  28.      * @param 设备连接信息
  29.      *            [sessions]
  30.      */
  31.     public void setSessions(Map<String, IoSession> sessions) {
  32.         this.sessions = sessions;
  33.     }
  34.     /**
  35.      * 增加设备连接信息[sessions]
  36.      *
  37.      * @param MAC地址作为键
  38.      *            [mac]
  39.      * @param IoSession对象作为值
  40.      *            [session]
  41.      */
  42.     public void save(String mac, IoSession session) {
  43.         sessions.put(mac, session);
  44.         String clientIp = session.getRemoteAddress().toString();
  45.         KVStoreUtils.putHashmapField(mac, value);
  46.         String kvIp = KVStoreUtils.getHashmapField(NetConstants.KV_PORT_KEY, mac);
  47.         if (StringUtil.isNotBlank(kvIp)) {
  48.             if (!kvIp.contains(clientIp)) {
  49.                 String ipvalue = kvIp + ";" + clientIp;
  50.                 KVStoreUtils.putHashmapField(NetConstants.KV_PORT_KEY, mac, ipvalue);
  51.             }
  52.         } else {
  53.             KVStoreUtils.putHashmapField(NetConstants.KV_PORT_KEY, mac, clientIp);
  54.         }
  55.     }
  56.     /**
  57.      * 查找设备连接信息[sessions]
  58.      *
  59.      * @param MAC地址作为键
  60.      *            [key]
  61.      * @return 连接信息
  62.      */
  63.     public IoSession isExists(String key) {
  64.         if (sessions.containsKey(key)) {
  65.             return sessions.get(key);
  66.         }
  67.         return null;
  68.     }
  69.     /**
  70.      * 删除设备连接信息[sessions]
  71.      *
  72.      * @param MAC地址作为键
  73.      *            [mac]
  74.      */
  75.     public void remove(String mac, String clientIp) {
  76.         sessions.remove(mac);
  77.         String ipvalue = KVStoreUtils.getHashmapField(NetConstants.KV_PORT_KEY, mac);
  78.         if (clientIp.equals(ipvalue)) {
  79.             KVStoreUtils.removeHahmapField(mac);
  80.             KVStoreUtils.removeHahmapField(NetConstants.KV_PORT_KEY, mac);
  81.         } else {
  82.             String ipvalueTemp = ipvalue.replaceAll(clientIp + ";", "");
  83.             KVStoreUtils.putHashmapField(NetConstants.KV_PORT_KEY, mac, ipvalueTemp);
  84.         }
  85.     }
  86. }

TCPServerHandler.java

  1. /**
  2.  * 服务端业务处理类
  3.  *
  4.  * @author Pactera.He
  5.  */
  6. public class PurifierTCPServerHandler extends IoHandlerAdapter {
  7.     private final static Log log = LogFactory.getLog(TCPServerHandler.class);
  8.     private final static Map<String, String> firstHeartBeatMap = new HashMap<String, String>();
  9.     public TCPServerHandler() {
  10.     }
  11.     @Override
  12.     public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
  13.         log.error(session.getRemoteAddress().toString() + " : " + cause.toString());
  14.     }
  15.     @Override
  16.     public void messageReceived(IoSession session, Object message) throws Exception {
  17.         // 消息内容
  18.         String text = message.toString();
  19.         // 获取客户端发过来的消息内容
  20.         log.info("接收消息内容 : " + text);
  21.         if (StringUtil.isNotBlank(text)) {
  22.             // 解析XML文件
  23.             readXML(text, session);
  24.         } else {
  25.             // 返回错误信息
  26.             session.write("error heartbeat");
  27.         }
  28.     }
  29.     @Override
  30.     public void messageSent(IoSession session, Object message) throws Exception {
  31.         log.debug("发送消息内容 : \n" + message.toString());
  32.     }
  33.     @Override
  34.     public void sessionCreated(IoSession session) throws Exception {
  35.         log.debug("连接创建 : " + session.getRemoteAddress().toString());
  36.     }
  37.     @Override
  38.     public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
  39.         log.info(MessageFormat.format("连接Idle [{0}] from {1} ", status, session.getRemoteAddress()));
  40.         if (status == IdleStatus.READER_IDLE) {
  41.             session.close(true);
  42.         }
  43.     }
  44.     @Override
  45.     public void sessionOpened(IoSession session) throws Exception {
  46.         if (checkIsBlocked(session)) {
  47.             session.close(true);
  48.             return;
  49.         }
  50.         log.info("连接打开:" + session.getRemoteAddress().toString());
  51.     }
  52.     @Override
  53.     public void sessionClosed(IoSession session) throws Exception {
  54.         if (checkIsBlocked(session)) {
  55.             return;
  56.         }
  57.         log.info("连接关闭 : " + session.getRemoteAddress().toString());
  58.         // 关闭通知
  59.         if (session.getAttribute("mac") != null) {
  60.             String mac = session.getAttribute("mac").toString();
  61.             firstHeartBeatMap.remove(mac);
  62.             this.notifyWeChat(mac, session.getRemoteAddress().toString());
  63.         }
  64.     }
  65.     /**
  66.      * session关闭通知WeChat
  67.      */
  68.     private void notifyWeChat(String mac, String clientIp) {
  69.         log.info("连接关闭:" + mac + ",通知微信 . . .");
  70.         if (StringUtil.isNotBlank(mac)) {
  71.             // 清除信息
  72.             SessionCache.getInstance().remove(mac, clientIp);
  73.         }
  74.     }
  75.     /**
  76.      * 解析XML文件
  77.      *
  78.      * @param contents
  79.      *            解析数据内容
  80.      * @param session
  81.      *            处理对象
  82.      */
  83.     private void readXML(String contents, IoSession session) throws DocumentException {
  84.         Document readDoc = DocumentHelper.parseText(contents);
  85.         Element rootNode = readDoc.getRootElement();
  86.         String mac = "";
  87.         // 匹配节点:tcp_msg
  88.         if (NetConstants.NODE_TCP_MSG.equals(rootNode.getName())) {
  89.             // 匹配节点(msg)内容
  90.             if (NetConstants.MSG_VALUE_HEARTBEAT.equals(rootNode.elementTextTrim(NetConstants.NODE_MSG))) {
  91.                 // mac address
  92.                 Element node = rootNode.element(NetConstants.NODE_DATA);
  93.                 mac = node.elementTextTrim(NetConstants.NODE_MAC_ADDRESS);
  94.                 // 生成所需XML文件
  95.                 createXML(mac, session, wifiVersion);
  96.             }
  97.         }
  98.     }
  99.     /**
  100.      * 生成XML文件
  101.      *
  102.      * @param mac
  103.      *            MAC地址
  104.      * @param session
  105.      *            处理对象
  106.      */
  107.     private void createXML(String mac, IoSession session, String wifiVersion) {
  108.         log.info("当前处理Mac地址 : " + mac);
  109.         if (StringUtil.isNotBlank(mac)) {
  110.             // 保存客户端的会话session
  111.             SessionCache.getInstance().save(mac, session);
  112.             // DocumentHelper提供了创建Document对象的方法
  113.             Document writeDoc = DocumentHelper.createDocument();
  114.             // 添加节点:tcp_msg
  115.             Element root = writeDoc.addElement(NetConstants.NODE_TCP_MSG);
  116.             // 添加节点:msg
  117.             Element msg = root.addElement(NetConstants.NODE_MSG);
  118.             // 设置节点信息
  119.             msg.setText(NetConstants.MSG_VALUE_HEARTBEATRES);
  120.             // 添加节点:cmd
  121.             Element cmd = root.addElement(NetConstants.NODE_CMD);
  122.             // 不再检查每个心跳包
  123.             cmd.setText(NetConstants.VALUE_NULL);
  124.             // 添加节点:data
  125.             Element data = root.addElement(NetConstants.NODE_DATA);
  126.             // 添加节点:server_time
  127.             Element server_time = data.addElement(NetConstants.NODE_SERVER_TIME);
  128.             // 设置节点信息
  129.             server_time.setText(String.valueOf(System.currentTimeMillis()));
  130.             // 将document文档对象直接转换成字符串
  131.             log.debug("发送内容: " + writeDoc.asXML());
  132.             session.write(writeDoc.asXML());
  133.         }
  134.     }
  135.     /**
  136.      * 检查对面地址是否在黑名单中
  137.      *
  138.      * @param session
  139.      *            连接session
  140.      * @return 是:true,否:false
  141.      */
  142.     private boolean checkIsBlocked(IoSession session) {
  143.         boolean ret = false;
  144.         String[] blockList = {};
  145.         for (String blocked : blockList) {
  146.             if (session.getRemoteAddress().toString().indexOf(blocked) > 0) {
  147.                 ret = true;
  148.                 break;
  149.             }
  150.         }
  151.         return ret;
  152.     }
  153. }

Mina与Spring整合

标签:

原文地址:http://www.cnblogs.com/codeydt/p/5126220.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!