Netty如何设置为Https访问
作者:微瞰技术 发布时间:2021-12-06 02:00:40
标签:Netty,设置,Https,访问
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


猜你喜欢
- 前言众所周知Java提供File类,让我们对文件进行操作,下面就来简单整理了一下File类的用法。 话不多说了,来一起看看详细的介绍吧1.基
- Java异常简介Java异常是Java提供的一种识别及响应错误的一致性机制。Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证
- 前言接着上一篇:Java Fluent Mybatis 项目工程化与常规操作详解流程篇 上仓库地址:GitHub仓库查询定义查询请求体pac
- 目录前言简单示例基础操作定时取消关联取消判断取消源码探究构造入手小插曲WaitHandle注册操作取消操作Cancel操作CancelAft
- C语言学习建议1.阅读文章一本更有意义又有趣的书《C专家编程》这本书叙述了各种各样趣味的八卦,例如设计方案一个程序流程来查验过道里的自动售卖
- 在Android Studio中对一个自己库进行生成操作时将会同时生成*.jar与*.aar文件。分别存储位置: &n
- Swagger以及knife4j基本使用Swagger 介绍:官网:https://swagger.io/Swagger是一个规范和完整的框
- 如何建立哈夫曼树的,网上搜索一堆,这里就不写了,直接给代码。1.哈夫曼树结点类:HuffmanNode.h#ifndef HuffmanNo
- 本文实例为大家分享了flutter实现底部导航栏切换的具体代码,供大家参考,具体内容如下思路:MaterialApp是提供了bottomna
- 前言本章内容主要研究一下java高级特性-反射、android注解、和 * 的使用,通过了解这些技术,可以为了以后实现组件化或者Api h
- Mybatis条件if test使用枚举值1.正确package com.weather.weatherexpert.common.util
- 面试题一:判断下列程序运行结果package String_test;public class test_1 { public static
- 前言:在工作中一次排查慢接口时,查到了一个函数耗时较长,最终定位到是通过 List 去重导致的。由于测试环境还有线上早期数据较少,这个接口的
- 本文实例讲述了C#通过指针读取文件的方法。分享给大家供大家参考。具体如下:// readfile.cs// 编译时使用:/unsafe//
- Gradle修改默认的Build配置文件名Gradle默认使用build.gradle作为默认的配置文件文件名。如果我们在build.gra
- 在日常开发中我们经常会使用到行情数据,很多的时候我们根据一个基准数据区构造行情,但是随着时间的推移然来构造的数据与真实行情数据之间的差距越来
- using System; using System.IO; using System.Threading; using System.Wi
- 前提首先,我们肯定要在Application里面注册一个CrashHandler,监听应用crashpublic class TestApp
- 1、使用pom安装依赖<dependency> <groupId>com.alibaba&
- 场景最近在做数据分析项目,里面有这样一个业务:把匹配的数据打上标签,放到新的索引中。数据量:累计亿级的数据使用场景:可能会单次查询大量的数据