在使用mina的过程中,我们通常会自定义各种报文,以使用于自己的业务。今天就为大家带来一款类似http协议的解码过程。
mina有自带的解析http数据包的解码类。可以使用maven配置一下内容获取源码:
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-http</artifactId>
<version>3.0.0-M2</version>
</dependency>
或者下载mina的源码包,查看org.apache.mina.http.HttpServerDecoder类。下面为自己写的解析方法:
package com.server;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
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.apache.mina.filter.codec.textline.LineDelimiter;
/**
* 解码HTTP协议类
* @author Herman.xiong
* @date 2015年7月16日09:36:59
* @version V3.0
* @since Tomcat6.0,Jdk1.6
* @copyright Copyright (c) 2015
*/
public class HttpServerDecoder extends CumulativeProtocolDecoder {
private static final Logger log = Logger.getLogger(HttpServerDecoder.class);
private LineDelimiter codecLineDelimiter = null;
private Charset charset = null;
private static final String MessageLength = "MessageLength";
public HttpServerDecoder(Charset charset, LineDelimiter codecLineDelimiter) {
this.charset = charset;
this.codecLineDelimiter = codecLineDelimiter;
}
public Charset getCharset() {
return charset;
}
public void setCharset(Charset charset) {
this.charset = charset;
}
public LineDelimiter getCodecLineDelimiter() {
return codecLineDelimiter;
}
public void setCodecLineDelimiter(LineDelimiter codecLineDelimiter) {
this.codecLineDelimiter = codecLineDelimiter;
}
public static void main(String [] args){
IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
Charset charset = Charset.forName("UTF-8");
CharsetEncoder ce=charset.newEncoder();
HttpServerDecoder socket=new HttpServerDecoder(Charset.forName("UTF-8"),LineDelimiter.CRLF);
try{
System.out.println("测试数据,测试数据".getBytes(charset).length);
buf.putString("MessageMethod:UserAction", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("MessageType:GET", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("Content-Type:text/html; charset=iso-8859-1", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("Connection:keep-alive", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("Keep-Alive:200", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("CompressType:jzip", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("Params:id=1&uid=2&name=3", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("accept-ranges:bytes", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("DateTime:DateTime", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.putString("MessageLength:27", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
//body
buf.putString("测试数据,测试数据", ce);
buf.putString(LineDelimiter.CRLF.getValue(), ce);
buf.flip();
System.out.println("输出的内容为:"+buf.getString(charset.newDecoder()));
buf.flip();
socket.doDecode(null,buf,null);
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 数据包解码
*/
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
Map<String,Object> map = (Map<String,Object>) session.getAttribute("pocket");
IoBuffer buf = (IoBuffer)session.getAttribute("pocket_state");
if(null ==buf)
buf = IoBuffer.allocate(100).setAutoExpand(true).setAutoShrink(true);
if(null == map)
map = new HashMap<String,Object>();
Integer len = 0;
while (in.hasRemaining()) {
len = 0;
byte b = in.get();
switch (b){
case '\r':
buf.put(b);
break;
case '\n':
buf.put(b);
buf.flip();
String msg=buf.getString(charset.newDecoder());
String[] arr = msg.split(":");
if(StringUtils.isEmpty(map.get("MessageLength"))){
if (2 == arr.length && StringUtils.isNotEmpty(arr[0]) && StringUtils.isNotEmpty(arr[1])) {
map.put(arr[0],arr[1]);
} else {
log.error("收到的数据包中存在非法内容!");
}
if(Constant.HUPU_ZERO.equals(map.get("MessageLength"))){
out.write(map);
if(in.position()==in.limit()){
session.setAttribute("pocket_state", null);
session.setAttribute("pocket",null);
return true;
}
map = new HashMap<String,Object>();
}
}else{
map.put(StringUtils.isEmpty(map.get("MessageContent"))?msg:map.get("MessageContent")+msg);
len=((null == map.get("MessageContent")) ? StringUtils.EMPTY : String.valueOf(map.get("MessageContent"))).getBytes(charset).length;
if(len==Integer.parseInt(map.get("MessageContent"))+2){
out.write(map);
if(in.position()==in.limit()){
session.setAttribute("pocket_state", null);
session.setAttribute("pocket",null);
return true;
}
}
map = new HashMap<String,Object>();
}
buf.clear();
break;
default:
buf.put(b);
}
}
if(StringUtils.isEmpty(map.get("MessageLength")) || len<Integer.parseInt(map.get("MessageLength"))){
session.setAttribute("pocket",map);
session.setAttribute("pocket_state", buf);
}
return false;
}
}
欢迎大家关注我的博客!如有疑问,请加QQ群:454796847共同学习!