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

 更新时间:2022年06月06日 10:13:24   作者:BtWangZhi  
这篇文章主要介绍了关于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();
          }
      }
}

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

相关文章

  • 如何解决IDEA使用Tomcat控制台中文出现乱码问题

    如何解决IDEA使用Tomcat控制台中文出现乱码问题

    这篇文章主要介绍了如何解决IDEA使用Tomcat控制台中文出现乱码问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Java timezone设置和mybatis连接数据库时区设置方式

    Java timezone设置和mybatis连接数据库时区设置方式

    这篇文章主要介绍了Java timezone设置和mybatis连接数据库时区设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • java构造函数示例(构造方法)

    java构造函数示例(构造方法)

    这篇文章主要介绍了java构造函数示例(构造方法),需要的朋友可以参考下
    2014-03-03
  • 时间中间键的整理

    时间中间键的整理

    这篇文章主要介绍了时间中间键的整理的相关资料,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,需要的朋友可以参考下
    2017-10-10
  • Java gbk转utf-8

    Java gbk转utf-8

    本文主要介绍了Java gbk转utf-8的方法,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • Java 中Flyway的使用详解

    Java 中Flyway的使用详解

    这篇文章主要介绍了Java 中Flyway的使用详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Java如何使用Query动态拼接SQL详解

    Java如何使用Query动态拼接SQL详解

    这篇文章主要给大家介绍了关于Java如何使用Query动态拼接SQL的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • java使用正则表达为数字添加千位符的简单方法

    java使用正则表达为数字添加千位符的简单方法

    这篇文章主要介绍了java使用正则表达为数字添加千位符的简单方法,需要的朋友可以参考下
    2014-04-04
  • java基础-数组扩容详解

    java基础-数组扩容详解

    这篇文章主要介绍了Java数组扩容实现方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-08-08
  • java TreeMap源码解析详解

    java TreeMap源码解析详解

    这篇文章主要介绍了java TreeMap源码解析详解的相关资料,需要的朋友可以参考下
    2017-04-04

最新评论