当前位置:首页 > 服务端 > Netty 实现http协议

Netty 实现http协议

2022年11月07日 08:29:25服务端8

这里简单介绍下,项目中使用netty在main方法中启动项目,实现http协议。

maven依赖的包

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>4.1.27.Final</version>
</dependency>

1、netty启动入口:

package com.fotile.cloud.ruleengin;

import javax.servlet.ServletException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import com.fotile.cloud.ruleengin.falsework.NettyHttpServer;

/**
 * Hello world!
 *
 */
public class RuleApplication
{

    // 引擎端口
    private final static int ENGINE_PORT = 8086;

    /**
     * http prot is 8085,
     */

    public static void main(String[] args)
    {
	// 加载spring配置
	ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
	DispatcherServlet servlet = getDispatcherServlet(ctx);
	NettyHttpServer server = new NettyHttpServer(ENGINE_PORT, servlet);
	server.start();

    }

    public static DispatcherServlet getDispatcherServlet(ApplicationContext ctx)
    {

	XmlWebApplicationContext mvcContext = new XmlWebApplicationContext();
	// 加载spring-mvc配置
	mvcContext.setConfigLocation("classpath:spring-mvc.xml");
	mvcContext.setParent(ctx);
	MockServletConfig servletConfig = new MockServletConfig(mvcContext.getServletContext(), "dispatcherServlet");
	DispatcherServlet dispatcherServlet = new DispatcherServlet(mvcContext);
	try
	{
	    dispatcherServlet.init(servletConfig);
	} catch (ServletException e)
	{
	    e.printStackTrace();
	}
	return dispatcherServlet;
    }
}

2、编写NettyHttpServer

package com.fotile.cloud.openplatform.falsework;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.DispatcherServlet;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyHttpServer implements Runnable
{

    private Logger LOGGER = Logger.getLogger(this.getClass());

    private int port;
    private DispatcherServlet servlet;

    public NettyHttpServer(Integer port)
    {
	this.port = port;
    }

    public NettyHttpServer(Integer port, DispatcherServlet servlet)
    {
	this.port = port;
	this.servlet = servlet;
    }

    public void start()
    {
	EventLoopGroup bossGroup = new NioEventLoopGroup();
	EventLoopGroup workerGroup = new NioEventLoopGroup();
	try
	{
	    ServerBootstrap b = new ServerBootstrap();
	    b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
		    .childHandler(new HttpServerInitializer(servlet)).option(ChannelOption.SO_BACKLOG, 128)
		    .childOption(ChannelOption.SO_KEEPALIVE, true);

	    LOGGER.info("NettyHttpServer Run successfully");
	    // 绑定端口,开始接收进来的连接
	    ChannelFuture f = b.bind(port).sync();
	    // 等待服务器 socket 关闭 。在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。
	    f.channel().closeFuture().sync();
	} catch (Exception e)
	{
	    System.out.println("NettySever start fail" + e);
	} finally
	{
	    workerGroup.shutdownGracefully();
	    bossGroup.shutdownGracefully();
	}
    }

    @Override
    public void run()
    {
	start();
    }
}

3、处理http请求、处理、返回

package com.fotile.cloud.ruleengin.falsework;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import io.netty.handler.codec.http.multipart.MemoryAttribute;
import io.netty.util.CharsetUtil;

import org.apache.commons.lang3.StringUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;

public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest>
{

    private DispatcherServlet servlet;

    public HttpRequestHandler(DispatcherServlet servlet)
    {
	this.servlet = servlet;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest) throws Exception
    {
	boolean flag = HttpMethod.POST.equals(fullHttpRequest.method())
		|| HttpMethod.GET.equals(fullHttpRequest.method()) || HttpMethod.DELETE.equals(fullHttpRequest.method())
		|| HttpMethod.PUT.equals(fullHttpRequest.method());

	Map<String, String> parammap = getRequestParams(ctx, fullHttpRequest);
	if (flag && ctx.channel().isActive())
	{
	    // HTTP请求、GET/POST
	    MockHttpServletResponse servletResponse = new MockHttpServletResponse();
	    MockHttpServletRequest servletRequest = new MockHttpServletRequest(
		    servlet.getServletConfig().getServletContext());
	    // headers
	    for (String name : fullHttpRequest.headers().names())
	    {
		for (String value : fullHttpRequest.headers().getAll(name))
		{
		    servletRequest.addHeader(name, value);
		}
	    }
	    String uri = fullHttpRequest.uri();
	    uri = new String(uri.getBytes("ISO8859-1"), "UTF-8");
	    uri = URLDecoder.decode(uri, "UTF-8");
	    UriComponents uriComponents = UriComponentsBuilder.fromUriString(uri).build();
	    String path = uriComponents.getPath();
	    path = URLDecoder.decode(path, "UTF-8");
	    servletRequest.setRequestURI(path);
	    servletRequest.setServletPath(path);
	    servletRequest.setMethod(fullHttpRequest.method().name());

	    if (uriComponents.getScheme() != null)
	    {
		servletRequest.setScheme(uriComponents.getScheme());
	    }
	    if (uriComponents.getHost() != null)
	    {
		servletRequest.setServerName(uriComponents.getHost());
	    }
	    if (uriComponents.getPort() != -1)
	    {
		servletRequest.setServerPort(uriComponents.getPort());
	    }

	    ByteBuf content = fullHttpRequest.content();
	    content.readerIndex(0);
	    byte[] data = new byte[content.readableBytes()];
	    content.readBytes(data);
	    servletRequest.setContent(data);

	    if (uriComponents.getQuery() != null)
	    {
		String query = UriUtils.decode(uriComponents.getQuery(), "UTF-8");
		servletRequest.setQueryString(query);
	    }
	    if (parammap != null && parammap.size() > 0)
	    {
		for (String key : parammap.keySet())
		{
		    servletRequest.addParameter(UriUtils.decode(key, "UTF-8"),
			    UriUtils.decode(parammap.get(key) == null ? "" : parammap.get(key), "UTF-8"));
		}
	    }
	    servlet.service(servletRequest, servletResponse);

	    HttpResponseStatus status = HttpResponseStatus.valueOf(servletResponse.getStatus());
	    String result = servletResponse.getContentAsString();
	    result = StringUtils.isEmpty(result) ? status.toString() : result;
	    FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status,
		    Unpooled.copiedBuffer(result, CharsetUtil.UTF_8));
	    response.headers().set("Content-Type", "text/json;charset=UTF-8");
	    response.headers().set("Access-Control-Allow-Origin", "*");
	    response.headers().set("Access-Control-Allow-Headers",
		    "Content-Type,Content-Length, Authorization, Accept,X-Requested-With,X-File-Name");
	    response.headers().set("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
	    response.headers().set("Content-Length", Integer.valueOf(response.content().readableBytes()));
	    response.headers().set("Connection", "keep-alive");
	    ChannelFuture writeFuture = ctx.writeAndFlush(response);
	    writeFuture.addListener(ChannelFutureListener.CLOSE);
	}
    }

    /**
     * 获取post请求、get请求的参数保存到map中
     */
    private Map<String, String> getRequestParams(ChannelHandlerContext ctx, HttpRequest req)
    {
	Map<String, String> requestParams = new HashMap<String, String>();
	// 处理get请求
	if (req.method() == HttpMethod.GET)
	{
	    QueryStringDecoder decoder = new QueryStringDecoder(req.uri());
	    Map<String, List<String>> parame = decoder.parameters();
	    Iterator<Entry<String, List<String>>> iterator = parame.entrySet().iterator();
	    while (iterator.hasNext())
	    {
		Entry<String, List<String>> next = iterator.next();
		requestParams.put(next.getKey(), next.getValue().get(0));
	    }
	}
	// 处理POST请求
	if (req.method() == HttpMethod.POST)
	{
	    HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), req);
	    List<InterfaceHttpData> postData = decoder.getBodyHttpDatas(); //
	    for (InterfaceHttpData data : postData)
	    {
		if (data.getHttpDataType() == HttpDataType.Attribute)
		{
		    MemoryAttribute attribute = (MemoryAttribute) data;
		    requestParams.put(attribute.getName(), attribute.getValue());
		}
	    }
	}
	return requestParams;
    }

}

启来后,使用postman,调用本地接口。

作者:net亮
来源链接:https://blog.csdn.net/u011038738/article/details/96998920

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/68283.html

标签: NettyHTTP
分享给朋友:

“Netty 实现http协议” 的相关文章

计算机网络基础必备(三次握手,四次握手,以及HTTP协议相关)

计算机网络基础必备(三次握手,四次握手,以及HTTP协议相关)

目录 一、计算机网络 通信协议 网络模型 二、TCP/IP...

Android与Netty服务器连接

参考了:https://blog.csdn.net/yulinxx/article/details/51085782 首先服务器使用Netty框架搭建,关于Netty环境的搭建参考Netty环境搭建(Eclipse) Android客户端也采用了Netty框架,环境搭...

SpringBoot 拦截器获取http请求参数

SpringBoot 拦截器获取http请求参数

SpringBoot 拦截器获取http请求参数—— 所有骚操作基础 目录 SpringBoot 拦截器获取http请求参数—— 所有骚操作基础 获取http请求参数是一种刚需 定义拦截器获取请求...

Maven如何配置HTTP代理

Maven如何配置HTTP代理

在企业开发,有很多公司考虑到网络安全都会使用内网,一些刚到公司的小伙伴装完环境后会发现, 因为连不上外网导致Maven库下不下来,这个时候就需要在Maven中配置代理。 具体操作步骤如下: 1.打开下载的Maven文件进去 conf 文件夹,找到 settings.xml...

webapi swagger自定义 HTTP Header验证用户

webapi swagger自定义 HTTP Header验证用户

问题描述 webapi自定义的一种验证方式(token放入header里),使用swagger测试时由于header里没值所以一直拿不到用户. 解决如下:(从标题2开始,标题1处处理全局验证用户) 1.新建GlobalAuthorizationFilter类...

IDEA:http://fls.jetbrains-agent.com-- No response

起因: win10电脑关机,打开,自动更新了系统。 (误删除vmoptions的-javaagent 绿色 jar包,也会出现↓。。。) [ 2022年1月14日改vmoptions这玩意又替换的别人后而忘了加 -javaagent:D:\idea\je...

微信开发的Http或Https常用工具类

前不久写了几篇有关微信定制开发的文章并整理成了专题,里面所有的文档都提到了CommonUtil这个工具类,关于这个工具类原本有写但是不是每篇博客都有,所以就有人找我要这个工具类,评论里也有好多人说不知道这个工具类怎么写,因此针对这些疑问就特意给大家贴一下代码 1  ...

python实现的json数据以HTTP GET,POST,PUT,DELETE方式页面请求

转自 http://blog.chinaunix.net/uid-26000296-id-4394470.html 一、JSON简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。...

AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher

今天使用OkHttp的时候遇到一个坑,加了句log后就报错 Log.d(TAG, "onResponse: "+ response.body().string()); String resp = response.body().string();  ...

HTTP请求(方法,格式;Fidder抓包;get与post请求的区别)

HTTP请求(方法,格式;Fidder抓包;get与post请求的区别)

目录 一,HTTP请求方法 常用请求方法 其他请求方法 二,HTTP请求作用 三,HTTP请求整体格式 常见的请求体数据类型: 四,使用Fidder抓包工具进行验证 验证GET请求 验证POST请求 五,GET和POST...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。