服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Netty如何设置为Https访问

Netty如何设置为Https访问

2023-02-15 14:46微瞰技术 Java教程

这篇文章主要介绍了Netty如何设置为Https访问,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Netty设置为Https访问

SSLContextFactory

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
        }
}

处理类 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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依赖的包

?
1
2
3
4
5
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.27.Final</version>
</dependency>

1.netty启动入口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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请求、处理、返回

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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

延伸 · 阅读

精彩推荐