使用mina解析http协议的使用

简介: 在使用mina的过程中,我们通常会自定义各种报文,以使用于自己的业务。今天就为大家带来一款类似http协议的解码过程。<br>mina有自带的解析http数据包的解码类。可以使用maven配置一下内容获取源码:<br><pre name="code" class="html"><dependency> <groupId>org.apache.mina</g
在使用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共同学习!
目录
相关文章
|
3天前
|
前端开发 API 网络架构
RESTful接口与http协议状态表述
该文介绍了RESTful风格API的好处和设计原则。RESTful API以资源为中心,通过HTTP方法(GET, POST, PUT, DELETE)表示操作,利用状态码反馈操作结果。它简化了客户端与服务端的交互,提供了一种通用规范,减少沟通成本。设计要点包括:URI描述资源,HTTP方法体现操作,使用标准HTTP状态码,GET不改变数据,使用复数名词,支持复杂资源关系,可选实现HATEOAS,以及接口版本管理。
|
4天前
|
缓存 负载均衡 网络协议
【亮剑】一次完整的 HTTP 请求过程,包括 DNS 解析、TCP 握手、HTTP 请求和响应等环节
【4月更文挑战第30天】本文介绍了HTTP请求的重要性和详细过程。首先,DNS解析将域名转换为IP地址,通过递归和迭代查询找到目标服务器。接着,TCP三次握手建立连接。然后,客户端发送HTTP请求,服务器处理请求并返回响应。最后,理解这个过程有助于优化网站性能,如使用DNS缓存、HTTP/2、Keep-Alive、CDN和负载均衡等实践建议。
|
4天前
|
安全 网络协议 算法
【计算机网络】http协议的原理与应用,https是如何保证安全传输的
【计算机网络】http协议的原理与应用,https是如何保证安全传输的
|
5天前
|
网络协议 安全 算法
HTTP协议与HTTPS协议
HTTP协议与HTTPS协议
|
6天前
|
前端开发 API UED
AngularJS的$http服务:深入解析与进行HTTP请求的技术实践
【4月更文挑战第28天】AngularJS的$http服务是核心组件,用于发起HTTP请求与服务器通信。$http服务简化了通信过程,通过深入理解和实践,能构建高效、可靠的前端应用。
|
7天前
|
监控 安全 网络虚拟化
|
8天前
|
网络安全
socks5代理连接成功无法访问http协议的站点
无法通过SOCKS5代理访问HTTP网站可能由多个原因引起,如代理服务器不支持HTTP、配置错误、防火墙阻拦、连接问题、身份验证失败、浏览器设置不当或服务器被封锁。检查并解决这些因素,若问题持续,需深入排查或联系服务提供商。
|
10天前
|
缓存 网络协议
HTTP 协议初探
HTTP 协议初探
29 1
|
15天前
|
安全 网络安全 数据安全/隐私保护
HTTPS协议
HTTPS协议
19 0
|
15天前
|
网络协议 安全 网络安全
Socks VS HTTP 谁才是最快的代理协议
Socks VS HTTP 谁才是最快的代理协议

推荐镜像

更多