使用mina解析http協議的使用
在使用mina的過程中,我們通常會自定義各種報文,以使用於自己的業務。今天就為大家帶來一款類似http協議的解碼過程。
mina有自帶的解析http資料包的解碼類。可以使用maven配置一下內容獲取原始碼:
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共同學習! 相關文章
- HTTP 協議完全解析HTTP協議
- [php]HTTP協議頭解析PHPHTTP協議
- QT使用 http 協議通訊的實現示例QTHTTP協議
- HTTP協議中PUT和POST使用區別HTTP協議
- Android使用http協議訪問網路AndroidHTTP協議
- RTSP協議、RTMP協議、HTTP協議的區別協議HTTP
- 02 前端HTTP協議(圖解HTTP) 之 簡單的HTTP協議前端HTTP協議圖解
- HTTP 協議HTTP協議
- [HTTP協議]HTTP協議
- http協議HTTP協議
- 修改CAS客戶端 使用簡單HTTP協議客戶端HTTP協議
- GOLANG使用簡單型別,在協議解析的妙用Golang型別協議
- okhttp 原始碼解析 – http 協議的實現 – 重定向HTTP原始碼協議
- okhttp 原始碼解析 - http 協議的實現 - 重定向HTTP原始碼協議
- Java - Apache Mina 自定義協議通訊JavaApache協議
- http協議分析HTTP協議
- 理解http協議HTTP協議
- HTTP協議概述HTTP協議
- HTTP 協議類HTTP協議
- HTTP協議(2)HTTP協議
- 小解http協議HTTP協議
- HTTP 協議的前世今生HTTP協議
- HTTP協議的特點HTTP協議
- 《圖解HTTP》——簡單的HTTP協議圖解HTTP協議
- 《圖解HTTP》—簡單的HTTP協議圖解HTTP協議
- HTTP協議和HTTPS協議的異同點?HTTP協議
- 使用者協議協議
- Swift代理協議的安全使用Swift協議
- HTTP 協議圖解HTTP協議圖解
- 瞭解HTTP協議HTTP協議
- HTTP協議那些事HTTP協議
- HTTP協議簡述HTTP協議
- HTTP 協議簡介HTTP協議
- Http協議簡介HTTP協議
- HTTP2 協議HTTP協議
- 簡述HTTP協議HTTP協議
- HTTP協議基礎HTTP協議
- Http協議入門HTTP協議