Netty如何设置为Https访问

目录
  • Netty设置为Https访问
    • SSLContextFactory
    • 处理类
  • Netty实现Http协议
    • maven依赖的包
    • 1.netty启动入口
    • 2.编写NettyHttpServer
    • 3.处理http请求、处理、返回

Netty设置为Https访问

SSLContextFactory

public class SSLContextFactory {
       public static SSLContext getSslContext() throws Exception {
            char[] passArray = "zhuofansoft".toCharArray();
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            KeyStore ks = KeyStore.getInstance("JKS");
            //鍔犺浇keytool 鐢熸垚鐨勬枃浠�
            FileInputStream inputStream = new FileInputStream("D://server.keystore");
           
            ks.load(inputStream, passArray);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(ks, passArray);
            sslContext.init(kmf.getKeyManagers(), null, null);
            inputStream.close();
            return sslContext;
        }
}

处理类

public class HttpsSeverHandler extends ChannelInboundHandlerAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpServerHandler.class);
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
        	HttpRequest request = (HttpRequest) msg;
        	 LOGGER.info("access messageReceived invoke success..");
             Long startTime = System.currentTimeMillis();
             // 400
             if (!request.decoderResult().isSuccess()) {
                 sendError(ctx, HttpResponseStatus.BAD_REQUEST);
                 return;
             }
             // 405
             if (request.method() != GET) {
                 sendError(ctx, HttpResponseStatus.METHOD_NOT_ALLOWED);
                 return;
             }
             FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.OK);
             Map<String, String> parmMap = new RequestParser((FullHttpRequest) request).parse();
             //jQuery跨域携带标识符
             String callback = parmMap.get("callback");
             LOGGER.info("connection jsonp header:[{}],request param:[{}]",callback,parmMap.get("requestParam"));;
             //请求参数
             DeviceRequest deviceRequest = JSONObject.parseObject(parmMap.get("requestParam"), DeviceRequest.class);

             DeviceResultWapper<?> result = getClientResponse(deviceRequest);
             LOGGER.info("get client response success.. response:[{}]",JSONObject.toJSONString(result));
             LOGGER.info("get client response take time:[{}]",(System.currentTimeMillis()-startTime)/1000+"s");
             String content = callback + "("+JSONObject.toJSONString(result)+")";
             byte[] bs = content.getBytes("UTF-8");
             response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
             response.headers().set(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(bs.length));
             response.content().writeBytes(ByteBuffer.wrap(bs));
             ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
/*            HttpRequest request = (HttpRequest) msg;
          boolean keepaLive = HttpUtil.isKeepAlive(request);

            System.out.println("method" + request.method());
            System.out.println("uri" + request.uri());
            FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
            httpResponse.content().writeBytes("https".getBytes());
            httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=UTF-8");
            httpResponse.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, httpResponse.content().readableBytes());
           if (keepaLive) {
                httpResponse.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
                ctx.writeAndFlush(httpResponse);
            } else {
                ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE);
           }*/
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        if (ctx.channel().isActive()) {
            sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR);
        }
    }
    private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
        FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, status,
                Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8));
        response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
/*    @Override
    protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        LOGGER.info("access messageReceived invoke success..");
        Long startTime = System.currentTimeMillis();
        // 400
        if (!request.decoderResult().isSuccess()) {
            sendError(ctx, HttpResponseStatus.BAD_REQUEST);
            return;
        }
        // 405
        if (request.method() != GET) {
            sendError(ctx, HttpResponseStatus.METHOD_NOT_ALLOWED);
            return;
        }
        FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.OK);
        Map<String, String> parmMap = new RequestParser(request).parse();
        //jQuery跨域携带标识符
        String callback = parmMap.get("callback");
        LOGGER.info("connection jsonp header:[{}],request param:[{}]",callback,parmMap.get("requestParam"));;
        //请求参数
        DeviceRequest deviceRequest = JSONObject.parseObject(parmMap.get("requestParam"), DeviceRequest.class);

        DeviceResultWapper<?> result = getClientResponse(deviceRequest);
        LOGGER.info("get client response success.. response:[{}]",JSONObject.toJSONString(result));
        LOGGER.info("get client response take time:[{}]",(System.currentTimeMillis()-startTime)/1000+"s");
        String content = callback + "("+JSONObject.toJSONString(result)+")";
        byte[] bs = content.getBytes("UTF-8");
        response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(bs.length));
        response.content().writeBytes(ByteBuffer.wrap(bs));
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
*/
    private DeviceResultWapper<?> getClientResponse(DeviceRequest deviceRequest) {
        // 拼接参数
        DeviceCommandVo deviceCommandVo = DeviceType.wapperRequestParam(deviceRequest);
        if (deviceCommandVo == null) {
            return DeviceResultWapper.fail(400, "remote user with illegal param");
        }
        SerialPortOrder serialPortOrder = DeviceOrderFactory.produce(deviceCommandVo.getDeviceTypeId());
        return serialPortOrder.order(deviceCommandVo);
    }
}

Netty实现Http协议

这里简单介绍下,项目中使用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,调用本地接口。

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

(0)

相关推荐

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

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

  • 如何开发基于Netty的HTTP/HTTPS应用程序

    目录 一.通过 SSL/TLS 保护应用程序 二.HTTP 编解码器 三.聚合 HTTP 消息 四.HTTP 压缩 五.HTTPS 六.WebSocket 一.通过 SSL/TLS 保护应用程序 SSL 和 TLS 安全协议层叠在其他协议之上,用以实现数据安全.为了支持 SSL/TLS,Java 提供了 javax.net.ssl 包,它的 SSLContext 和 SSLEngine 类使得实现解密和加密变得相当简单.Netty 通过一个名为 SsLHandler 的 ChannelHandl

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

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

  • Netty如何设置为Https访问

    目录 Netty设置为Https访问 SSLContextFactory 处理类 Netty实现Http协议 maven依赖的包 1.netty启动入口 2.编写NettyHttpServer 3.处理http请求.处理.返回 Netty设置为Https访问 SSLContextFactory public class SSLContextFactory {        public static SSLContext getSslContext() throws Exception {   

  • Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

    HTTPS简介 HTTPS(Hyper Text Transfer Protocol Secure),是一种基于SSL/TLS的HTTP,所有的HTTP数据都是在SSL/TLS协议封装之上进行传输的.HTTPS协议是在HTTP协议的基础上,添加了SSL/TLS握手以及数据加密传输,也属于应用层协议.Https使用的默认端口是443.更多HTTPS原理可以参考阮一峰老师的文章:http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html SSL证书 证书类

  • nginx开启HSTS让浏览器强制跳转HTTPS访问详解

    在上一篇文章中我们已经实现了本地node服务使用https访问了,看上一篇文章效果可以看如下: 但是如果我们现在使用http来访问的话,访问不了.如下图所示: 因此我现在首先要做的是使用nginx配置下,当用户在浏览器下输入http请求的时候使用nginx重定向到https下即可.因此我们现在需要做一个简单的nginx重定向功能. 因此在我们的nginx中需要加如下重定向配置: server { listen xxx.abc.com; server_name xxx.abc.com; rewri

  • nginx使用ssl模块配置支持HTTPS访问的方法

    默认情况下ssl模块并未被安装,如果要使用该模块则需要在编译nginx时指定–with-http_ssl_module参数. 需求: 做一个网站域名为 www.localhost.cn 要求通过https://www.localhost.cn进行访问. 10.10.100.8 www.localhost.cn 实验步骤: 1.首先确保机器上安装了openssl和openssl-devel #yum install openssl #yum install openssl-devel 2.创建服务

  • docker安装nginx并配置通过https访问的方法

    1. 下载最新的nginx的docker image $ docker pull nginx:latest 2. 启动nginx容器 运行如下命令来启动nginx container docker run --detach \ --name wx-nginx \ -p 443:443\ -p 80:80 \ -v /home/evan/workspace/wxserver/nginx/data:/usr/share/nginx/html:rw\ -v /home/evan/workspace/w

  • SpringBoot 改造成https访问的实现

    SpringBoot https改造 1.生成密钥证书 生成命令:keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 (1)关键字解释: alias 密钥别名 storetype 指定密钥仓库类型 keyalg 生证书的算法名称,RSA是一种非对称加密算法 keysize 证书大小 keystore 生成的证书文件的存储路径

  • Nginx域名转发https访问的实现

    说在前面的话: 突然接到这么一个任务,将多个域名的访问必须使用https的转发访问,其实对Niginx的使用很简单,文档也很齐全(不管是腾讯云还是阿里云),入坑的原因是对Niginx服务器的陌生和走的弯路. 1.弯路:Tomcat支持SSL 腾讯云Tomcat服务器证书配置 修改server.xml文件 <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSL

  • Nodejs在局域网配置https访问的实现方法

    零.需求: 做一个局域网WebRTC视频聊天系统,需要用到HTTPS.因此,配置Node.js使其支持HTTPS访问. 一.解决 在线生成和证书 访问:https://csr.chinassl.net/generator-csr.html 填写好之后点生成即可,我们可以下载到两个文件. 这里我的域名是192.168.110.10,得到192.168.110.10_csr.txt和192.168.110.10_key.txt这两个文件(妥善保存). 然后再访问:https://csr.chinas

  • nginx如何将http访问的网站改成https访问

    1. 背景 我有个用于数据展示的网站使用nginx对外提供http访问,另外一个系统用超链接的方式跳转到我的网站提供给终端用户访问.后来对方说他们的站点是https访问的,不能直接访问http,所以需要我支持https访问. 所以这里仅限于展示类网站的参考,交互式网站我也不会. ***对nginx的了解仅限于可以通过配置文件完成网站访问的配置,其他没有深入理解.*** 2. 预备知识 https: HTTPS(全称:Hyper Text Transfer Protocol over Secure

  • Java通过SSLEngine与NIO实现HTTPS访问的操作方法

    目录 一.连接服务器之前先初始化SSLContext并设置证书相关的操作. 1.1 基于公钥CA 1.2 加载Java KeyStore 二.连接服务器成功后,需要创建SSLEngine对象,并进行相关设置与握手处理. 三.进行握手操作 3.1 握手相关状态(来自getHandshakeStatus方法) 3.2处理握手的方法 四.数据的发送与接收 4.1加密操作(SelectionKey.OP_WRITE) 4.2 解密操作(SelectionKey.OP_READ) Java使用NIO进行H

随机推荐