Apache Mina:一个简单的http的服务器并响应json数据的Demo

Apache Mina:一个简单的http的服务器并响应json数据的Demo,第1张

Apache Mina:一个简单的http的服务器并响应json数据的Demo

当前版本:jdk1.8

1. 声明

当前内容主要为使用Apache Mina实现一个简单的http服务器,并完成默认json数据的响应,当前内容参考:apache mina源码

主要pom依赖


	org.apache.mina
	mina-core
	2.1.5


	org.apache.mina
	mina-http
	2.1.5



	org.apache.mina
	mina-transport-serial
	2.1.5

2. Demo实现

一个简单的服务器Server

public class HttpServer {
	public static void main(String[] args) {

		IoAcceptor acceptor = new NioSocketAcceptor();
		LoggingFilter loggingFilter = new LoggingFilter();
		loggingFilter.setMessageReceivedLogLevel(LogLevel.DEBUG);
		acceptor.getFilterChain().addLast("log", loggingFilter);
		acceptor.getFilterChain().addLast("httpServerCodec", new HttpServerCodec());
		acceptor.setHandler(new HttpServerHandler());
		try {
			acceptor.bind(new InetSocketAddress("localhost", 8081));
			System.out.println("start http server....");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
}

httpServer对应的处理Handler

import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.http.DateUtil;
import org.apache.mina.http.api.DefaultHttpResponse;
import org.apache.mina.http.api.HttpEndOfContent;
import org.apache.mina.http.api.HttpMethod;
import org.apache.mina.http.api.HttpRequest;
import org.apache.mina.http.api.HttpStatus;
import org.apache.mina.http.api.HttpVersion;

public class HttpServerHandler extends IoHandlerAdapter {
	private static final CharsetEncoder ENCODER = StandardCharsets.UTF_8.newEncoder();

	@Override
	public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
		// TODO Auto-generated method stub
		super.sessionIdle(session, status);
		System.out.println("idle ==>" + status);
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
		// TODO Auto-generated method stub
		super.exceptionCaught(session, cause);
		session.closeNow();
	}

	List requestBody;

	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		// TODO Auto-generated method stub
		// super.messageSent(session, message);
		System.out.println("message sent");
	}

	@Override
	public void messageReceived(IoSession session, Object message) throws Exception {
		// TODO Auto-generated method stub
		// super.messageReceived(session, message);
		// 当前的message就是HttpRequest的实现类
		if (message == null) {
			return;
		}
		HttpRequest httpRequest = null;
		if (message instanceof HttpRequest) {
			httpRequest = (HttpRequest) message;
			// 获取请求路径
			String requestPath = httpRequest.getRequestPath();
			// 获取请求类型
			HttpMethod method = httpRequest.getMethod();
			// 获取请求参数
			String queryString = httpRequest.getQueryString();
			

			System.out.println("url:" + requestPath);
			System.out.println("method:" + method);
			System.out.println("queryString:" + queryString);
			System.out.println("httpRequest");
		} else if (message instanceof ByteBuffer) {
			// 接受post请求的消息体
			requestBody.add((ByteBuffer) message);
			System.out.println("byteBuffer");
		} else if (message instanceof HttpEndOfContent) {
			// we received all the post content, send the crap back
			sendResponse(session);
			System.out.println("httpEndOfContent");
		}

	}

	// 发送json结果到前台
	public void sendResponse(IoSession session) {
		System.out.println("send response....");
		// 写出默认响应
		writeDefaultResponse(session);
		String jsonResult = "{"status":"ok"}";
		// 写出body
		writeJsonBody(jsonResult, session);
		// 写出结束
		session.write(new HttpEndOfContent());
		session.close(false);

	}

	private Map createHeaders() {
		Map headers = new HashMap();
		headers.put("Server", "Apache MINA Server");
		headers.put("Date", DateUtil.getCurrentAsString());
		headers.put("Connection", "keep-alive");
		headers.put("Content-Language", "zh-CN");
		headers.put("Content-Type", "application/json; charset=utf-8");
		return headers;
	}

	private void writeDefaultResponse(IoSession session) {
		Map headers = createHeaders();
		DefaultHttpResponse defaultHttpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SUCCESS_OK,
				headers);
		session.write(defaultHttpResponse);
	}

	private void writeJsonBody(String json, IoSession session) {
		IoBuffer buf = IoBuffer.allocate(json.length()).setAutoExpand(true);
		try {
			buf.putString(json, ENCODER);
			buf.flip();
			session.write(buf);
		} catch (CharacterCodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

这里的HttpServerCodec具有解码和加码类

3. 测试结果

首先启动当前的server:该server默认在8081端口

访问当前的http://localhost:8081/login得到响应结果如下:

测试成功!

4. 主要易错的地方

这里主要出现的问题是如何响应http客户端的问题(找到Encoder即可解决问题),响应数据是要encoder的,server接受数据是decoder

由于是http请求所以可以定位到HttpServerEncoder

所以实际响应为(这个也对应请求中的部分):

  1. 首先发送httpResonse主要写出响应状态、http的版本、headers等并写出一个换行
  2. 如果有ByteBuffer就会写出(对应http响应中的body)
  3. 最后写出一个HttpEndOfContent表示http的响应内容结束

注意写出的数据必须使用IoBuffer 作为写出的body(直接使用ByteBuffer好像没有作用

IoBuffer buf = IoBuffer.allocate(json.length()).setAutoExpand(true);
buf.putString(json, ENCODER);
buf.flip();

自此一个完整的http请求响应就完成了

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5693339.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存