关于Netty--Http请求处理方式

目录
  • Netty--Http请求处理
    • 业务处理逻辑
  • Netty处理简单Http请求的例子
    • 废话不多说 上代码

Netty--Http请求处理

1.这几天在看Netty权威指南,代码敲了一下,就当做个笔记吧。

/**
 * Http服务端
 * @author Tang
 * 2018年5月13日
 */
public class HttpServer {
	public void run(String url,Integer port) {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		ServerBootstrap bootstrap = new ServerBootstrap();
		bootstrap.group(bossGroup, workerGroup);
		bootstrap.channel(NioServerSocketChannel.class);
		bootstrap.childHandler(new ChannelInitializer<Channel>() {
			@Override
			protected void initChannel(Channel ch) throws Exception {
				ch.pipeline().addLast("http-decoder", new HttpRequestDecoder());
				ch.pipeline().addLast("http-aggregator",
						new HttpObjectAggregator(65536));
				ch.pipeline()
						.addLast("http-encoder", new HttpResponseEncoder());
				ch.pipeline()
						.addLast("http-chunked", new ChunkedWriteHandler());
				ch.pipeline().addLast("http-handler", new HttpServerHandler());
			}
		});
		try {
			ChannelFuture channelFuture = bootstrap.bind(url, port).sync();
			channelFuture.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}
	public static void main(String[] args) {
		new HttpServer().run("127.0.0.1",8001);
	}
}

业务处理逻辑

public class HttpServerHandler extends
		SimpleChannelInboundHandler<FullHttpRequest> {
	@Override
	protected void messageReceived(ChannelHandlerContext ctx,
			FullHttpRequest fullHttpRequest) throws Exception {
		// 构造返回数据
		JSONObject jsonRootObj = new JSONObject();
		JSONObject jsonUserInfo = new JSONObject();
		jsonUserInfo.put("id", 1);
		jsonUserInfo.put("name", "张三");
		jsonUserInfo.put("password", "123");
		jsonRootObj.put("userInfo", jsonUserInfo);
		// 获取传递的数据
		Map<String, Object> params = getParamsFromChannel(ctx, fullHttpRequest);
		jsonRootObj.put("params", params);
		FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK);
		response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8");
		StringBuilder bufRespose = new StringBuilder();
		bufRespose.append(jsonRootObj.toJSONString());
		ByteBuf buffer = Unpooled.copiedBuffer(bufRespose, CharsetUtil.UTF_8);
		response.content().writeBytes(buffer);
		buffer.release();
		ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}
	/**
	 * 获取传递的参数
	 *
	 * @param ctx
	 * @param fullHttpRequest
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private static Map<String, Object> getParamsFromChannel(
			ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest)
			throws UnsupportedEncodingException {
		HttpHeaders headers = fullHttpRequest.headers();
		String strContentType = headers.get("Content-Type").trim();
		System.out.println("ContentType:" + strContentType);
		Map<String, Object> mapReturnData = new HashMap<String, Object>();
		if (fullHttpRequest.getMethod() == HttpMethod.GET) {
			// 处理get请求
			QueryStringDecoder decoder = new QueryStringDecoder(
					fullHttpRequest.getUri());
			Map<String, List<String>> parame = decoder.parameters();
			for (Entry<String, List<String>> entry : parame.entrySet()) {
				mapReturnData.put(entry.getKey(), entry.getValue().get(0));
			}
			System.out.println("GET方式:" + parame.toString());
		} else if (fullHttpRequest.getMethod() == HttpMethod.POST) {
			// 处理POST请求
			if (strContentType.contains("x-www-form-urlencoded")) {
				HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(
						new DefaultHttpDataFactory(false), fullHttpRequest);
				List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
				for (InterfaceHttpData data : postData) {
					if (data.getHttpDataType() == HttpDataType.Attribute) {
						MemoryAttribute attribute = (MemoryAttribute) data;
						mapReturnData.put(attribute.getName(),
								attribute.getValue());
					}
				}
			} else if (strContentType.contains("application/json")) {
				// 解析json数据
				ByteBuf content = fullHttpRequest.content();
				byte[] reqContent = new byte[content.readableBytes()];
				content.readBytes(reqContent);
				String strContent = new String(reqContent, "UTF-8");
				System.out.println("接收到的消息" + strContent);
				JSONObject jsonParamRoot = JSONObject.parseObject(strContent);
				for (String key : jsonParamRoot.keySet()) {
					mapReturnData.put(key, jsonParamRoot.get(key));
				}
			} else {
				FullHttpResponse response = new DefaultFullHttpResponse(
						HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR);
				ctx.writeAndFlush(response).addListener(
						ChannelFutureListener.CLOSE);
			}
			System.out.println("POST方式:" + mapReturnData.toString());
		}
		return mapReturnData;
	}
}

支持Get和PostContentType为application/json、x-www-form-urlencoded的处理。

用Postman亲测无问题。

Netty处理简单Http请求的例子

废话不多说 上代码

HttpHelloWorldServerInitializer.java

import io.netty.channel.ChannelInitializer;
  import io.netty.channel.ChannelPipeline;
  import io.netty.channel.socket.SocketChannel;
  import io.netty.handler.codec.http.HttpServerCodec;
  import io.netty.handler.ssl.SslContext;
  public class HttpHelloWorldServerInitializer extends ChannelInitializer<SocketChannel> {
      private final SslContext sslCtx;
      public HttpHelloWorldServerInitializer(SslContext sslCtx) {
         this.sslCtx = sslCtx;
      }
      @Override
      public void initChannel(SocketChannel ch) {
          ChannelPipeline p = ch.pipeline();
          if (sslCtx != null) {
              p.addLast(sslCtx.newHandler(ch.alloc()));
          }
          p.addLast(new HttpServerCodec());
          p.addLast(new HttpHelloWorldServerHandler());
      }
  }

HttpHelloWorldServerHandler.java

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderUtil;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpRequest;
import static io.netty.handler.codec.http.HttpHeaderNames.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*;
  public class HttpHelloWorldServerHandler extends ChannelHandlerAdapter {
      private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };
      @Override
      public void channelReadComplete(ChannelHandlerContext ctx) {
          ctx.flush();
      }
      @Override
      public void channelRead(ChannelHandlerContext ctx, Object msg) {
          if (msg instanceof HttpRequest) {
              HttpRequest req = (HttpRequest) msg;
              if (HttpHeaderUtil.is100ContinueExpected(req)) {
                  ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
              }
              boolean keepAlive = HttpHeaderUtil.isKeepAlive(req);
              FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT));
              response.headers().set(CONTENT_TYPE, "text/plain");
              response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());
              if (!keepAlive) {
                  ctx.write(response).addListener(ChannelFutureListener.CLOSE);
              } else {
                  response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
                  ctx.write(response);
              }
          }
      }
      @Override
      public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
          cause.printStackTrace();
          ctx.close();
      }
  }

HttpHelloWorldServer.java

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.SelfSignedCertificate;
/**
 * An HTTP server that sends back the content of the received HTTP request
 * in a pretty plaintext form.
 */
public final class HttpHelloWorldServer {
      static final boolean SSL = System.getProperty("ssl") != null;
      static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8443" : "8080"));
      public static void main(String[] args) throws Exception {
          // Configure SSL.
          final SslContext sslCtx;
          if (SSL) {
              SelfSignedCertificate ssc = new SelfSignedCertificate();
              sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
          } else {
              sslCtx = null;
          }
          // Configure the server.
          EventLoopGroup bossGroup = new NioEventLoopGroup(1);
          EventLoopGroup workerGroup = new NioEventLoopGroup();
          try {
              ServerBootstrap b = new ServerBootstrap();
              b.option(ChannelOption.SO_BACKLOG, 1024);
              b.group(bossGroup, workerGroup)
               .channel(NioServerSocketChannel.class)
               .handler(new LoggingHandler(LogLevel.INFO))
               .childHandler(new HttpHelloWorldServerInitializer(sslCtx));
              Channel ch = b.bind(PORT).sync().channel();
              System.err.println("Open your web browser and navigate to " +
                      (SSL? "https" : "http") + "://127.0.0.1:" + PORT + '/');
              ch.closeFuture().sync();
          } finally {
              bossGroup.shutdownGracefully();
              workerGroup.shutdownGracefully();
          }
      }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 如何用Netty实现高效的HTTP服务器

    1 概述 HTTP 是基于请求/响应模式的:客户端向服务器发送一个 HTTP 请求,然后服务器将会返回一个 HTTP 响应.Netty 提供了多种编码器和解码器以简化对这个协议的使用.一个HTTP 请求/响应可能由多个数据部分组成,FullHttpRequest 和FullHttpResponse 消息是特殊的子类型,分别代表了完整的请求和响应.所有类型的 HTTP 消息(FullHttpRequest.LastHttpContent 等等)都实现了 HttpObject 接口. (1) Htt

  • 关于Netty--Http请求处理方式

    目录 Netty--Http请求处理 业务处理逻辑 Netty处理简单Http请求的例子 废话不多说 上代码 Netty--Http请求处理 1.这几天在看Netty权威指南,代码敲了一下,就当做个笔记吧. /** * Http服务端 * @author Tang * 2018年5月13日 */ public class HttpServer { public void run(String url,Integer port) { EventLoopGroup bossGroup = new N

  • Java Netty HTTP服务实现过程解析

    超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议. 在后端开发中接触HTTP协议的比较多,目前大部分都是基于Servlet容器实现的Http服务,往往有一些核心子系统对性能的要求非常高,这个时候我们可以考虑采用NIO的网络模型来实现HTTP服务,以此提高性能和吞吐量,Netty除了开发网络应用非常方便,还内置了HTTP相关的编解码器,让用户可以很方便的开发出高性能的HTTP协议的服务,Spring Webflux默认是使用的N

  • ajax前台后台跨域请求处理方式

    最近一直在搞公众号前台开发,遇到了ajax跨域请求的问题,像地区的省-市-县三级联动.汽车品牌-车系-车款的三级联动查询等都需要调用外部接口(其他工程项目的接口)完成.下面就分享一下个人解决跨域请求的方案,当然是在后台程序猿大哥的帮助下,我才弄明白了其中的渊源,赶紧记录下来慢慢积累,也希望对大家能有所帮助,还请积极提出意见或建议. 跨域请求需要借助后台代码接收callback回调函数,对json数据进行进一步处理:前台再用ajax请求向服务器发送callback参数,并指定数据格式为jsonp.

  • springboot整合netty框架的方式小结

    目录 方式一:注解@PostConstruct 方式二:利用监听器启动: 方式三 :利用ApplicationListener 上下文监听器 方式四:commiandLinerunner启动 netty作为一个高性能的io框架,是非好用的一个技术框架, Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户.服务端应用.Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务

  • 深入浅析Netty 在 Dubbo 中是如何应用的

    众所周知,国内知名框架 Dubbo 底层使用的是 Netty作为网络通信,那么内部到底是如何使用的呢?今天我们就来一探究竟. 1. dubbo 的 Consumer 消费者如何使用 Netty 注意:此次代码使用了从 github 上 clone 的 dubbo 源码中的 dubbo-demo 例子. 代码如下: System.setProperty("java.net.preferIPv4Stack", "true"); ClassPathXmlApplicati

  • 分布式Netty源码分析EventLoopGroup及介绍

    目录 EventLoopGroup介绍 功能1:先来看看注册Channel 功能2:执行一些Runnable任务 EventLoop介绍 NioEventLoop介绍 EpollEventLoop介绍 后续 EventLoopGroup介绍 在前面一篇文章中提到了,EventLoopGroup主要负责2个事情,这里再重复下: 它主要包含2个方面的功能,注册Channel和执行一些Runnable任务. 功能1:先来看看注册Channel 即将Channel注册到Selector上,由Select

  • 游戏服务器中的Netty应用以及源码剖析

    目录 一.Reactor模式和Netty线程模型 1. BIO模型 2. NIO模型 3. Reacor模型 ①. 单Reacor单线程模型 ②. 单Reactor多线程模型 ③. 主从Reactor多线程模型 ④. 部分源码分析 二.select/poll和epoll 1.概念 2.jdk提供selector 3.Netty提供的Epoll封装 4.Netty相关类图 5.配置Netty为EpollEventLoop 三.Netty相关参数 1.SO_KEEPALIVE 2.SO_REUSEA

  • Java利用Sping框架编写RPC远程过程调用服务的教程

    RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. RPC 可基于 HTTP 或 TCP 协议,Web Service 就是基于 HTTP 协议的 RPC,它具有良好的跨平台性,但其性能却不如基于 TCP 协议的 RPC.会两方面会直接影响 RPC 的性能,一是传输方式,二是序列化. 众所周知,TCP 是传输层协议,HTTP 是应用层协议,而传输层较应用层更加底层,在数据传输方面,越底层越快,因此,在一般情况下

  • Windows下的PHP安装文件线程安全和非线程安全的区别

    从2000年10月20日发布的第一个Windows版的PHP3.0.17开始的都是线程安全的版本,这是由于与Linux/Unix系统是采用 多进程的工作方式不同的是Windows系统是采用多线程的工作方式.如果在IIS下以CGI方式运行PHP会非常慢,这是由于CGI模式是建立在多进程 的基础之上的,而非多线程.一般我们会把PHP配置成以ISAPI的方式来运行,ISAPI是多线程的方式,这样就快多了.但存在一个问题,很多常用的 PHP扩展是以Linux/Unix的多进程思想来开发的,这些扩展在IS

  • 解决Tomcat修改get提交请求乱码问题

    1:表单提交controller获得中文参数后乱码解决方案 注意: jsp页面编码设置为UTF-8 ***************form表单提交方式为必须为post,get方式下面spring编码过滤器不起效果 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <form action="/user/addUser" n

  • 轻量级asp.net ajax解决方案详解

    本文实例讲述了轻量级asp.net ajax解决方案.分享给大家供大家参考,具体如下: 跟shotdog老师研究探讨了下asp.net里,除官方庞大asp.net ajax之外的ajax解决方案.我们想法是以不同的服务器端方式输出,然后在页面使用jQuery的ajax实现调用服务器端几个解决方案: 1.使用一般的webform,在页面用jQuery ajax调用,再从取得的html数据中取得<body>内的内容,写入DOM 优点:不用改变现有的asp.net开发模式,可以使用现成的页面:aja

随机推荐