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

}

欢迎大家关注我的博客!如有疑问,请加QQ群:454796847共同学习!

时间: 2024-12-04 04:18:30

使用mina解析http协议的使用的相关文章

markup-apache mina 解析消息体时出现丢失情况

问题描述 apache mina 解析消息体时出现丢失情况 mina在解析消息体时,出现消息体丢失的情况,如下: <?xml version="1.0" encoding="UTF-8"?>nulltext1425542871725client_send_text<![CDATA[CONFIRM_ORDER{"CUR_MESSAGE":{"TIPS":{"TIP":"请您按时前往

未解析-Http协议 get请求页面,返回的为什么是未经过解析的代码?

问题描述 Http协议 get请求页面,返回的为什么是未经过解析的代码? 为什么返回的是这个未经过解析的结果? <html> <head> <META NAME="robots" CONTENT="noindex,nofollow"> <script> (function() { function getSessionCookies() { cookieArray = new Array(); var cName =

解析Ftp协议的两种工作模式

Ftp协议的两种工作模式:主动模式active和被动模式passive FTP 是一种数据传输协议 (File Transfer Protocol),它的连接模式有两种: 主动模式( active )和被动模式( passive ). 以下说明FTP的连接是怎样建立的: 在 active 模式下 (一般预设的模式): FTP client 开启一个随机选择的TCP port 呼叫 FTP server 的 port 21请求建立连接.当完成 Three-Way Handshake 之后,连接就成

wireshark解析rtp协议,流媒体中的AMR/H263/H264包的方法

抓到完整的流媒体包之后,用wireshark打开,其中的包可能不会自动映射成RTP+AMR/H263/H264的包,做如下修改操作即可:1.  把UDP 包解析成RTP/RTCP包.选中UDP包,右键,选择Decode As,选RTP2.  把RTP Payload映射成实际的媒体格式.首先查看RTSP中的SDP的payload_type,比如96是H263,97是AMR.那么点击菜单Edit -> Preference -> Protocol, AMR payload_type number

CAN 协议解析及如何取出指定位

问题描述 CAN 协议解析及如何取出指定位 请问一下,这个协议具体的意思.该如何解析这个协议. 共八字节的数据,如何分别解析呀? 解决方案 http://wenku.baidu.com/link?url=RTD5IIG6zaWCDvV3B2rTDuTOZ3vzPAcHOdjl8y7Bcn89n4TR2-pKjYo25h2QPj5vkmrVwCy_Zcv84P7pmlgLbrS7dkTtY5Kg_6v64-J-NZa

用C#解析接收到的WITS协议数据,传输方式是UDP

问题描述 用C#解析WITS协议数据,就是将WITS网口接收数据格式进行解析,例如0201770000解析出来的结果是:钻井深度数据表井名770000.已完成的是UDP协议的通讯,现在要做的是把接收到的数据解析出来,02是什么,01是什么,770000是什么.并且要逐行解析出来,例如解析02017700000202002032020425020512042602068414102072,逐行解析.求大神帮忙!!! 解决方案 解决方案二:这个你得按这个协议标准去写代码--估计现成的C#代码很危险,

实时-关于RTP协议的问题 java语言

问题描述 关于RTP协议的问题 java语言 我先说下我的情况 无线摄像头模块+路由器+android手机 我的android手机已经可以实现查看摄像画面了,但是不流畅,总比电脑上显示的摄像画面要慢很多,动作不能太大,太大画面反应就慢了 我用的surfaceview,利用线程将摄像画面一帧一帧的加载到surfaceview上的. 现在我查到RTP协议可以实现实时视频文件传输,不太了解RTP协议,我是解析http协议的. 我有几个问题: 1.我见有的网友代码里写的是"rtp://xxx.xx.xx

基于HTTP的QQ协议(转)

大家说到QQ协议都觉得很神秘,是因为QQ不像MSN或者ICQ协议都已经官方公布了,而QQ的没有公布.研究 它的人也不是特别的多,虽然已经有了基于QQ协议所写成的第三方软件 foicq, qq plugins for gaim, LumaQQ,但是由于他们是基于二进制Stream的协议过于复杂,大家阅读代码也有一定的难度,再加上网络 上解析QQ协议的文章也不是十分多,所以基于QQ网络协议的应用程序也是寥寥无几的.现在我就把基于HT TP的QQ协议进行一个粗浅的剖析,希望对大家有所帮助.源码部分就用

基于OPC协议的工控网络系统防护浅析

一.协议概述 提到OPC协议,大家想到最多的就是OPC Classic 3.0,实际上现在OPC协议有两个大类,一种是基于微软COM/DCOM技术的"Classic",另一种是基于Web service的OPC UA.前者在DCOM协议之上,诞生较早,已广泛应用在各种工业控制系统现场,成为工业自动化领域的事实标准.后者与前者比出生较晚,但在设计时考虑了安全因素,有了加密机制,不过目前应用范围较小.本文主要讨论的是前者在工控系统中的防护. 微软的DCOM协议是在网络安全问题被广泛认识之前