java mina http_基于Mina的Http Server以及简单的Http请求客户端

packagecom.ajita.httpserver;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.StringReader;importjava.nio.charset.CharacterCodingException;importjava.nio.charset.Charset;importjava.nio.charset.CharsetDecoder;importjava.util.HashMap;importjava.util.Map;importorg.apache.mina.core.buffer.IoBuffer;importorg.apache.mina.core.session.IoSession;importorg.apache.mina.filter.codec.ProtocolDecoderOutput;importorg.apache.mina.filter.codec.demux.MessageDecoderAdapter;importorg.apache.mina.filter.codec.demux.MessageDecoderResult;public class HttpRequestDecoder extendsMessageDecoderAdapter {private static final byte[] CONTENT_LENGTH = new String("Content-Length:")

.getBytes();staticString defaultEncoding;privateCharsetDecoder decoder;publicCharsetDecoder getDecoder() {returndecoder;

}public voidsetEncoder(CharsetDecoder decoder) {this.decoder =decoder;

}private HttpRequestMessage request = null;publicHttpRequestDecoder() {

decoder=Charset.forName(defaultEncoding).newDecoder();

}publicMessageDecoderResult decodable(IoSession session, IoBuffer in) {try{return messageComplete(in) ?MessageDecoderResult.OK

: MessageDecoderResult.NEED_DATA;

}catch(Exception ex) {

ex.printStackTrace();

}returnMessageDecoderResult.NOT_OK;

}publicMessageDecoderResult decode(IoSession session, IoBuffer in,

ProtocolDecoderOutput out)throwsException {

HttpRequestMessage m=decodeBody(in);//Return NEED_DATA if the body is not fully read.

if (m == null) {returnMessageDecoderResult.NEED_DATA;

}

out.write(m);returnMessageDecoderResult.OK;

}/** 判断HTTP请求是否完整,若格式有错误直接抛出异常*/

private booleanmessageComplete(IoBuffer in) {int last = in.remaining() - 1;if (in.remaining() < 4) {return false;

}//to speed up things we check if the Http request is a GET or POST

if (in.get(0) == (byte) 'G' && in.get(1) == (byte) 'E'

&& in.get(2) == (byte) 'T') {//Http GET request therefore the last 4 bytes should be 0x0D 0x0A//0x0D 0x0A

return in.get(last) == (byte) 0x0A

&& in.get(last - 1) == (byte) 0x0D

&& in.get(last - 2) == (byte) 0x0A

&& in.get(last - 3) == (byte) 0x0D;

}else if (in.get(0) == (byte) 'P' && in.get(1) == (byte) 'O'

&& in.get(2) == (byte) 'S' && in.get(3) == (byte) 'T') {//Http POST request//first the position of the 0x0D 0x0A 0x0D 0x0A bytes

int eoh = -1;for (int i = last; i > 2; i--) {if (in.get(i) == (byte) 0x0A && in.get(i - 1) == (byte) 0x0D

&& in.get(i - 2) == (byte) 0x0A

&& in.get(i - 3) == (byte) 0x0D) {

eoh= i + 1;break;

}

}if (eoh == -1) {return false;

}for (int i = 0; i < last; i++) {boolean found = false;for (int j = 0; j < CONTENT_LENGTH.length; j++) {if (in.get(i + j) !=CONTENT_LENGTH[j]) {

found= false;break;

}

found= true;

}if(found) {//retrieve value from this position till next 0x0D 0x0A

StringBuilder contentLength = newStringBuilder();for (int j = i + CONTENT_LENGTH.length; j < last; j++) {if (in.get(j) == 0x0D) {break;

}

contentLength.append(newString(new byte[] { in.get(j) }));

}//if content-length worth of data has been received then//the message is complete

returnInteger.parseInt(contentLength.toString().trim())+ eoh ==in.remaining();

}

}

}//the message is not complete and we need more data

return false;

}privateHttpRequestMessage decodeBody(IoBuffer in) {

request= newHttpRequestMessage();try{

request.setHeaders(parseRequest(newStringReader(in

.getString(decoder))));returnrequest;

}catch(CharacterCodingException ex) {

ex.printStackTrace();

}return null;

}private MapparseRequest(StringReader is) {

Map map = new HashMap();

BufferedReader rdr= newBufferedReader(is);try{//Get request URL.

String line =rdr.readLine();

String[] url= line.split(" ");if (url.length < 3) {returnmap;

}

map.put("URI", newString[] { line });

map.put("Method", new String[] { url[0].toUpperCase() });

map.put("Context", new String[] { url[1].substring(1) });

map.put("Protocol", new String[] { url[2] });//Read header

while ((line = rdr.readLine()) != null && line.length() > 0) {

String[] tokens= line.split(": ");

map.put(tokens[0], new String[] { tokens[1] });

}//If method 'POST' then read Content-Length worth of data

if (url[0].equalsIgnoreCase("POST")) {int len = Integer.parseInt(map.get("Content-Length")[0]);char[] buf = new char[len];if (rdr.read(buf) ==len) {

line=String.copyValueOf(buf);

}

}else if (url[0].equalsIgnoreCase("GET")) {int idx = url[1].indexOf('?');if (idx != -1) {

map.put("Context",new String[] { url[1].substring(1, idx) });

line= url[1].substring(idx + 1);

}else{

line= null;

}

}if (line != null) {

String[] match= line.split("\\&");for(String element : match) {

String[] params= new String[1];

String[] tokens= element.split("=");switch(tokens.length) {case 0:

map.put("@".concat(element), newString[] {});break;case 1:

map.put("@".concat(tokens[0]), newString[] {});break;default:

String name= "@".concat(tokens[0]);if(map.containsKey(name)) {

params=map.get(name);

String[] tmp= new String[params.length + 1];for (int j = 0; j < params.length; j++) {

tmp[j]=params[j];

}

params= null;

params=tmp;

}

params[params.length- 1] = tokens[1].trim();

map.put(name, params);

}

}

}

}catch(IOException ex) {

ex.printStackTrace();

}returnmap;

}

}packagecom.ajita.httpserver;importjava.io.ByteArrayOutputStream;importjava.io.IOException;importjava.text.SimpleDateFormat;importjava.util.Date;importjava.util.HashMap;importjava.util.Map;importorg.apache.mina.core.buffer.IoBuffer;public classHttpResponseMessage {/**HTTP response codes*/

public static final int HTTP_STATUS_SUCCESS = 200;public static final int HTTP_STATUS_NOT_FOUND = 404;/**Map*/

private final Map headers = new HashMap();/**Storage for body of HTTP response.*/

private final ByteArrayOutputStream body = new ByteArrayOutputStream(1024);private int responseCode =HTTP_STATUS_SUCCESS;publicHttpResponseMessage() {//headers.put("Server", "HttpServer (" + Server.VERSION_STRING + ')');

headers.put("Server", "HttpServer (" + "Mina 2.0" + ')');

headers.put("Cache-Control", "private");

headers.put("Content-Type", "text/html; charset=iso-8859-1");

headers.put("Connection", "keep-alive");

headers.put("Keep-Alive", "200");

headers.put("Date", newSimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz").format(newDate()));

headers.put("Last-Modified", newSimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz").format(newDate()));

}public MapgetHeaders() {returnheaders;

}public voidsetContentType(String contentType) {

headers.put("Content-Type", contentType);

}public void setResponseCode(intresponseCode) {this.responseCode =responseCode;

}public intgetResponseCode() {return this.responseCode;

}public void appendBody(byte[] b) {try{

body.write(b);

}catch(IOException ex) {

ex.printStackTrace();

}

}public voidappendBody(String s) {try{

body.write(s.getBytes());

}catch(IOException ex) {

ex.printStackTrace();

}

}publicIoBuffer getBody() {returnIoBuffer.wrap(body.toByteArray());

}public intgetBodyLength() {returnbody.size();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值