Netty如何设置为Https访问

网友投稿 559 2022-07-26


目录Netty设置为Https访问SSLContextFactory处理类 Netty实现Http协议maven依赖的包1.netty启动入口2.编写NettyHttpServer3.处理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 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 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.xsGVeQcSGCLOSE);

}

*/

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依赖的包

io.netty

netty-all

4.1.27.Final

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

{

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 parammap = getRequestParams(ctx, fullHttpRequest);

if (flag && ctx.channel().isActive())

{

// HTTP请求、GET/POST

MockHttpServletResponse servletResponse = new MockHttpServletResponse();

MockHttpServletRequest servletReqhttp://uest = 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 getRequestParams(ChannelHandlerContext ctx, HttpRequest req)

{

Map requestParams = new HashMap();

// 处理get请求

if (req.method() == HttpMethod.GET)

{

QueryStringDecoder decoder = new QueryStringDecoder(req.uri());

Map> parame = decoder.parameters();

Iterator>> iterator = parame.entrySet().iterator();

while (iterator.hasNext())

{

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:UniApp + SpringBoot 实现微信支付和退款功能
下一篇:java数据结构与算法数组模拟队列示例详解(编写实现队列的例程,使用数组)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~