Netty如何设置为Https访问

作者:微瞰技术 时间:2021-12-06 02:00:40 

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,调用本地接口。

来源:https://zhaozhen.blog.csdn.net/article/details/83352819

标签:Netty,设置,Https,访问
0
投稿

猜你喜欢

  • Android引导页面的简单实现

    2023-08-06 04:24:32
  • java中Object类4种方法详细介绍

    2023-11-03 16:06:12
  • 结合线程池实现apache kafka消费者组的误区及解决方法

    2023-08-06 15:40:31
  • Spring整合Dubbo框架过程及原理解析

    2022-01-31 01:49:16
  • Java中的Unsafe在安全领域的使用总结和复现(实例详解)

    2023-07-30 10:58:42
  • Java实现LeetCode(1.两数之和)

    2021-06-03 02:11:19
  • 腾讯云部署javaWeb项目的实现步骤

    2023-11-05 18:03:29
  • Java使用新浪微博API通过账号密码方式登陆微博的实例

    2023-09-23 05:35:38
  • 在Java中按值调用和按引用调用

    2021-12-26 20:09:21
  • SpringBoot中使用Session共享实现分布式部署的示例代码

    2022-10-17 04:27:54
  • Android SharedPreferences实现记住密码和自动登录界面

    2023-06-15 20:07:00
  • web.xml SpringBoot打包可执行Jar运行SpringMVC加载流程

    2023-11-24 07:40:52
  • 详解Spring Bean的集合注入和自动装配

    2023-02-18 15:02:58
  • java数据结构之希尔排序

    2023-11-08 18:16:18
  • springboot 定时任务@Scheduled实现解析

    2023-11-10 16:18:24
  • 一文了解Java读写锁ReentrantReadWriteLock的使用

    2023-10-12 19:28:21
  • Java类的初始化顺序知识点总结

    2021-09-23 23:19:26
  • Java流程控制语句最全汇总(上篇)

    2023-11-03 01:57:48
  • java使用influxDB数据库的详细代码

    2023-03-04 05:22:27
  • 解决SpringMVC项目连接RabbitMQ出错的问题

    2022-12-22 13:05:51
  • asp之家 软件编程 m.aspxhome.com