Mina工具類
package com.cucpay.tradeportal.util;import java.net.InetSocketAddress; import java.nio.charset.Charset;
import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.future.ReadFuture; import org.apache.mina.core.service.IoConnector; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.ProtocolDecoderAdapter; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import org.apache.mina.filter.codec.ProtocolEncoderAdapter; import org.apache.mina.filter.codec.ProtocolEncoderOutput; import org.apache.mina.transport.socket.nio.NioSocketConnector;
/**
- 使用Mina2.x發送報文的工具類
- @create Oct 3, 2012 12:42:21 PM
- @author 玄玉<http://blog.csdn/net/jadyer>
- @version v1.1
@history v1.1-->編碼器和解碼器中的字符處理,升級為Mina2.x提供的<code>putString()</code>方法來處理 */ public class MinaUtil { private MinaUtil(){}
/**
- 發送TCP消息
- @see default timeout of the connect is 1 minute
- @see 該方法與遠程主機間通信的協議報文為"GB18030"編碼后的byte[]
- @param message 待發送報文的中文字符串形式
- @param ipAddress 遠程主機的IP地址
- @param port 遠程主機的端口號
- @return 遠程主機響應報文的字符串形式,若對方未響應or響應為null則返回<code>""</code>空字符串 */ public static String sendTCPMessage(String message, String ipAddress, int port){ IoConnector connector = new NioSocketConnector(); connector.setHandler(new ClientHandler(message)); connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new DefaultEncode(TradeCode.CHARSET_BUSIPLATFORM.toString()), new DefaultDecode(TradeCode.CHARSET_BUSIPLATFORM.toString()))); ConnectFuture connectFuture = connector.connect(new InetSocketAddress(ipAddress, port)); connectFuture.awaitUninterruptibly(); //等待連接成功,相當于將異步執行轉為同步執行 IoSession session = connectFuture.getSession(); //獲取連接成功后的會話對象 session.getConfig().setUseReadOperation(true); //設置IoSession的read()方法為可用,默認為false ReadFuture readFuture = session.read(); //因其內部使用BlockingQueue,故Server端用之可能會內存泄漏,但Client端可適當用之 readFuture.awaitUninterruptibly(); //Wait until the message is received Object respData = readFuture.getMessage(); //Get the received message return respData==null ? "":respData.toString(); //Returns the received message }
private static class ClientHandler extends IoHandlerAdapter {
private String message;
public ClientHandler(String message){
this.message = message;
}
@Override
public void sessionOpened(IoSession session) throws Exception {
session.write(message); //ClientHandler會將message傳到DefaultEncode,然后將報文發出
}
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
session.close(false); //關閉IoSession,該操作是異步的,true為立即關閉,false為所有寫操作都flush后關閉
session.getService().dispose(); //IoSession.close()僅僅是關閉了TCP的連接通道,并未關閉Client端程序
}
}
private static class DefaultEncode extends ProtocolEncoderAdapter {
private final String charset;
public DefaultEncode(String charset){
this.charset = charset;
}
@Override
public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
// IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true); // buffer.put(message.toString().getBytes(charset)); // buffer.flip(); //limit=position,position=0 // out.write(buffer); /**
* 上面的注釋內容,作用效果與下面相同,推薦使用Mina2.x提供的putString()
*/
IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true);
buffer.putString(message.toString(), Charset.forName(charset).newEncoder());
buffer.flip();
out.write(buffer);
}
}
private static class DefaultDecode extends ProtocolDecoderAdapter {
private final String charset;
public DefaultDecode(String charset){
this.charset = charset;
}
@Override
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
// if(in.hasArray()){ // System.out.println(LogUtil.formatTenToHexDataWithAscii(in.array(), 0, in.limit())); // } // byte[] len = new byte[6]; //假設報文長度固定為6 // in.get(len, 0, 6); // String msgLen = new String(len); // byte[] body = new byte[Integer.parseInt(msgLen)-6]; // in.get(body); //讀取IoBuffer中的所有剩余字節到byte[]中 // String msgBody = new String(body, charset); //報文中可能含中文,故指定解碼字符集 // //接收到報文長度-->000158 // //接收到完整報文-->00015800000000訂單結果通知:商戶系統未成功接收到通知,需要繼續通知 4263351542024162852720121019004138201210191` // System.out.println("接收到報文長度-->" + msgLen); // System.out.println("接收到完整報文-->" + msgLen + msgBody); // out.write(msgLen + msgBody); /**
* 上面的注釋內容,作用效果與下面相同,推薦使用Mina2.x提供的putString()
*/
IoBuffer buffer = IoBuffer.allocate(158)/*.setAutoExpand(true)*/;
while(in.hasRemaining()){ //判斷position和limit之間是否有元素
buffer.put(in.get()); //get()讀取此緩沖區當前position的字節,然后position+1
}
buffer.flip();
out.write(buffer.getString(Charset.forName(charset).newDecoder()));
}
}
}</pre>來自:http://blog.csdn.net/jadyer/article/details/8088068