使用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-10-30 04:41:46

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

apache MINA之心跳协议运用

摘要 心跳协议,对基于CS模式的系统开发来说是一种比较常见与有效的连接检测方式,最近在用MINA框架,原本自己写了一个心跳协议实现,后来突然发现MINA本身带有这样一个心跳实现,感于对框架的小小崇拜,在实践的同时研究了一下! MINA TCP/IP SOCKET 心跳 MINA本身提供了一个过滤器类: org.apache.mina.filter.keepalive . KeepAliveFilter ,该过滤器用于在IO空闲的时候发送并且反馈心跳包(keep-alive request/res

PHP解析Http协议

本文使用PHP解析Http协议 HTTP协议如下,包含两部分:请求头和请求体,我们主要是解析请求头,获取cookie,get,post等信息. HTTP/1.1 200 OK Date: Sun, 25 Oct 2015 15:43:47 GMT Server: Apache Set-Cookie: PHPSESSID=4v2actjf96v614r2kh36380kq6; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control:

一篇文章为你深度解析HTTPS 协议

一.前言 微信小程序如期发布,开发者在接入微信小程序过程中,会遇到以下问题: 小程序要求必须通过 HTTPS 完成与服务端通信,若开发者选择自行搭建 HTTPS 服务,那需要自行 SSL 证书申请.部署,完成 https 服务搭建,效率低流程冗长;且 HTTPS 的 SSL 加解析,对服务器的 CPU 有极大的开销. 其实,不仅仅是小程序,苹果 iOS 平台,Google Android 在 2017 也逐步强制要求开发者使用 HTTPS 接入.HTTPS 似乎是一个绕不开的门槛,让不少开发者头

SuperSocket 1.6.4 通过FixedHeaderReceiveFilter解析自定义协议

SuperSocket 提供了一些通用的协议解析工具, 你可以用他们简单而且快速的实现你自己的通信协议: TerminatorReceiveFilter (SuperSocket.SocketBase.Protocol.TerminatorReceiveFilter, SuperSocket.SocketBase) CountSpliterReceiveFilter (SuperSocket.Facility.Protocol.CountSpliterReceiveFilter, SuperSo

MINA之心跳协议运用

转自:http://my.oschina.net/yjwxh/blog/174633 摘要 心跳协议,对基于CS模式的系统开发来说是一种比较常见与有效的连接检测方式,最近在用MINA框架,原本自己写了一个心跳协议实现,后来突然发现MINA本身带有这样一个心跳实现,感于对框架的小小崇拜,在实践的同时研究了一下! MINA TCP/IP SOCKET 心跳 MINA本身提供了一个过滤器类: org.apache.mina.filter.keepalive . KeepAliveFilter ,该过滤

java网络编程客户端与服务端原理以及用URL解析HTTP协议

常见客户端与服务端 客户端: 浏览器:IE 服务端: 服务器:web服务器(Tomcat),存储服务器,数据库服务器. (注:会用到Tomact服务器,在webapps下有一个自己创建的目录myweb,下面有一个文件1.html) 服务端原理 自定义一个服务端,使用自己已有的客户端IE浏览器,了解一下客户端都发送了什么请求. 1 package cn.ie_server; 2 3 import java.io.IOException; 4 import java.io.InputStream;

【Java TCP/IP Socket】构建和解析自定义协议消息(含代码)

在传输消息时,用Java内置的方法和工具确实很用,如:对象序列化,RMI远程调用等.但有时候,针对要传输的特定类型的数据,实现自己的方法可能更简单.容易或有效.下面给出一个实现了自定义构建和解析协议消息的Demo(书上例子). 该例子是一个简单的投票协议.这里,一个客户端向服务器发送一个请求消息,消息中包含了一个候选人的ID,范围在0~1000.程序支持两种请求:一种是查询请求,即向服务器询问候选人当前获得的投票总数,服务器发回一个响应消息,包含了原来的候选人ID和该候选人当前获得的选票总数:另

android中gps的使用以及解析nmea0183协议

毕业设计中需要用到安卓的gps定位,总结一下这几天学到的关于gps相关的. 为了测试,所以布局文件很简单,只有两个TextView <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"

解析http协议的url

package util; import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.util.List;import java.util.Map;import java.util.Set; public class ServerUtil{ public static StringBu