使用mina解析http协议的使用

在使用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;
	}
	
}   

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券