在许多网络应用中可能针对传输的数据进行加密操作,接收到数据之后进行解码操作。
在mina中提供许多加密和解密的解析方式:
1.带一定前缀的字符串的解析方式。
2.序列化对象的字符串解析方式。
3.分隔符方式的字符串解析方式。
在mina中提供相关的filterchain支持相关的操作。
Mina的源代码如下:
package org.apache.mina.filter.codec; import org.apache.mina.core.session.IoSession; /** * Provides {@link ProtocolEncoder} and {@link ProtocolDecoder} which translates * binary or protocol specific data into message object and vice versa. * <p> * Please refer to * <a href="../../../../../xref-examples/org/apache/mina/examples/reverser/ReverseProtocolProvider.html"><code>ReverserProtocolProvider</code></a> * example. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ public interface ProtocolCodecFactory { /** * Returns a new (or reusable) instance of {@link ProtocolEncoder} which * encodes message objects into binary or protocol-specific data. */ ProtocolEncoder getEncoder(IoSession session) throws Exception; /** * Returns a new (or reusable) instance of {@link ProtocolDecoder} which * decodes binary or protocol-specific data into message objects. */ ProtocolDecoder getDecoder(IoSession session) throws Exception; }
加密处理类:
package org.apache.mina.filter.codec; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; /** * Encodes higher-level message objects into binary or protocol-specific data. * MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)} * method with message which is popped from the session write queue, and then * the encoder implementation puts encoded messages (typically {@link IoBuffer}s) * into {@link ProtocolEncoderOutput} by calling {@link ProtocolEncoderOutput#write(Object)}. * <p> * Please refer to * <a href="../../../../../xref-examples/org/apache/mina/examples/reverser/TextLineEncoder.html"><code>TextLineEncoder</code></a> * example. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> * * @see ProtocolEncoderException */ public interface ProtocolEncoder { /** * Encodes higher-level message objects into binary or protocol-specific data. * MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)} * method with message which is popped from the session write queue, and then * the encoder implementation puts encoded messages (typically {@link IoBuffer}s) * into {@link ProtocolEncoderOutput}. * * @throws Exception if the message violated protocol specification */ void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception; /** * Releases all resources related with this encoder. * * @throws Exception if failed to dispose all resources */ void dispose(IoSession session) throws Exception; }
解密类如下:
package org.apache.mina.filter.codec; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; /** * Decodes binary or protocol-specific data into higher-level message objects. * MINA invokes {@link #decode(IoSession, IoBuffer, ProtocolDecoderOutput)} * method with read data, and then the decoder implementation puts decoded * messages into {@link ProtocolDecoderOutput} by calling * {@link ProtocolDecoderOutput#write(Object)}. * <p> * Please refer to * <a href="../../../../../xref-examples/org/apache/mina/examples/reverser/TextLineDecoder.html"><code>TextLineDecoder</code></a> * example. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> * * @see ProtocolDecoderException */ public interface ProtocolDecoder { /** * Decodes binary or protocol-specific content into higher-level message objects. * MINA invokes {@link #decode(IoSession, IoBuffer, ProtocolDecoderOutput)} * method with read data, and then the decoder implementation puts decoded * messages into {@link ProtocolDecoderOutput}. * * @throws Exception if the read data violated protocol specification */ void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception; /** * Invoked when the specified <tt>session</tt> is closed. This method is useful * when you deal with the protocol which doesn't specify the length of a message * such as HTTP response without <tt>content-length</tt> header. Implement this * method to process the remaining data that {@link #decode(IoSession, IoBuffer, ProtocolDecoderOutput)} * method didn't process completely. * * @throws Exception if the read data violated protocol specification */ void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception; /** * Releases all resources related with this decoder. * * @throws Exception if failed to dispose all resources */ void dispose(IoSession session) throws Exception; }
在androidpn中的没有采取任何加密方式,但是提供相关的类org.androidpn.server.xmpp.codec,如果需要可以针对传输的数据进行加密和解密工作。
package org.androidpn.server.xmpp.codec; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFactory; import org.apache.mina.filter.codec.ProtocolDecoder; import org.apache.mina.filter.codec.ProtocolEncoder; /** * Factory class that specifies the encode and decoder to use for parsing XMPP stanzas. * * @author Sehwan Noh ([email protected]) */ public class XmppCodecFactory implements ProtocolCodecFactory { private final XmppEncoder encoder; private final XmppDecoder decoder; /** * Constructor. */ public XmppCodecFactory() { encoder = new XmppEncoder(); decoder = new XmppDecoder(); } /** * Returns a new (or reusable) instance of ProtocolEncoder. */ public ProtocolEncoder getEncoder(IoSession session) throws Exception { return encoder; } /** * Returns a new (or reusable) instance of ProtocolDecoder. */ public ProtocolDecoder getDecoder(IoSession session) throws Exception { return decoder; } }
androidpn的解密类:
package org.androidpn.server.xmpp.codec; import org.androidpn.server.xmpp.net.XmppIoHandler; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.CumulativeProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import org.jivesoftware.openfire.nio.XMLLightweightParser; /** * Decoder class that parses ByteBuffers and generates XML stanzas. * * @author Sehwan Noh ([email protected]) */ public class XmppDecoder extends CumulativeProtocolDecoder { // private final Log log = LogFactory.getLog(XmppDecoder.class); @Override public boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { // log.debug("doDecode(...)..."); XMLLightweightParser parser = (XMLLightweightParser) session .getAttribute(XmppIoHandler.XML_PARSER); parser.read(in); if (parser.areThereMsgs()) { for (String stanza : parser.getMsgs()) { out.write(stanza); } } return !in.hasRemaining(); } }
androidpn的加密类:
package org.androidpn.server.xmpp.codec; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolEncoder; import org.apache.mina.filter.codec.ProtocolEncoderOutput; /** * Encoder class that does nothing (to the already encoded data). * * @author Sehwan Noh ([email protected]) */ public class XmppEncoder implements ProtocolEncoder { // private final Log log = LogFactory.getLog(XmppEncoder.class); public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { // log.debug("encode()..."); } public void dispose(IoSession session) throws Exception { // log.debug("dispose()..."); } }
最终将编码解析器转换为过滤器使用,具体配置如下:
<bean class="org.apache.mina.filter.codec.ProtocolCodecFilter"> <constructor-arg> <bean class="org.androidpn.server.xmpp.codec.XmppCodecFactory" /> </constructor-arg> </bean>