• SpringBoot配置https(SSL证书)


    第一步:
    首先得明白什么是wss协议:

    可以看这篇文章:WSS、SSL 和 https 之间的关系

    第二步:
    先拿到ssl证书:我这边是用的阿里云的免费证书具体获取方法如下:

    先登录阿里云官网找到SSL证书选项,然后申请免费证书,然后下载tomcat证书。
    
    • 1

    可以参考:阿里云申请免费 SSL证书 https 的图文教程_林中明月间丶-CSDN博客_阿里云申请免费ssl证书
    在这里插入图片描述
    将下载的证书压缩包解压,找到后缀为.pfx的证书文件导入我们的springboot项目,如图:
    在这里插入图片描述

    然后在springboot的配置文件里面配置相应的属性(证书密码在解压后的pfx-password.txt文件中可以查看),我这边是配置了两个端口http和https都能访问该项目,同理ws和wss协议也都是支持的。

    server.ssl.key-store=classpath:证书名称.pfx
    # 密码
    server.ssl.key-store-password=证书密码
    # 秘钥证书库类型
    server.ssl.keyStoreType=PKCS12
    #这里先放一个参数,一会儿再程序中直接@Value获取
    myhttp.port=9097
    # 此端口为HTTPS端口
    server.port=9095
    在这里插入代码片
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    添加依赖:

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    import com.wanma.display.center.ds.DynamicDataSourceRegister;
    import org.apache.catalina.Context;
    import org.apache.catalina.connector.Connector;
    import org.apache.tomcat.websocket.server.WsSci;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
    import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
    import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Import;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @SpringBootApplication
    @Import(DynamicDataSourceRegister.class)
    @EnableScheduling
    public class DisplayCenterApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DisplayCenterApplication.class, args);
        }
    
        @Value("${myhttp.port}")
        private Integer httpPort;
    
    
        @Bean
        public ServletWebServerFactory servletContainer() {
            TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
            tomcat.addAdditionalTomcatConnectors(createHTTPConnector());
            return tomcat;
        }
    
        private Connector createHTTPConnector() {
            Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
            connector.setScheme("http");
            connector.setSecure(false);
            connector.setPort(httpPort);
            return connector;
        }
    
        /**
         * 创建wss协议接口
         *
         * @return
         */
        @Bean
        public TomcatContextCustomizer tomcatContextCustomizer() {
            System.out.println("websocket init");
            return new TomcatContextCustomizer() {
                @Override
                public void customize(Context context) {
                    System.out.println("init   customize");
                    context.addServletContainerInitializer(new WsSci(), null);
                }
            };
        }
    }
    
    
    • 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

    添加WebSocketConfig 配置类

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    @Configuration
    public class WebSocketConfig  {
    
        @Bean
        public ServerEndpointExporter serverEndpointExporter(){
            return new ServerEndpointExporter();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    然后在启动项目。

    到这里所有的配置都已经结束了,接下来就是测试了。

    websocket 代码:

    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import javax.websocket.OnClose;
    import javax.websocket.OnError;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    
    @ServerEndpoint("/ws/{token}") // 指定建立连接使用的URI
    @Component
    public class WebSocketServer {
    
        private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
        /**
         * 用于存储Session的Map,key为连接标识
         */
        public static final Map<String, Session> SESSION_MAP = new ConcurrentHashMap<>();
    
        /**
         * 连接建立
         * 从请求的URL:ws://localhost:8091/ws/{token}参数里面获取标识token
         */
        @OnOpen
        public void onOpen(@PathParam("token") String token, Session session){
            LOGGER.info("长连接已建立,用户:" + token);
            System.out.println("长连接已建立,用户:" + token);
            // 存储连接session,在需要用的地方直接使用
            SESSION_MAP.put(token,session);
        }
    
    //    /**
    //     * 收消息
    //     */
    //    @OnMessage
    //    public void onMessage(){
    //    }
    
    
        /**
         * 连接断开
         * @param token
         * @param session
         */
        @OnClose
        public void onClose(@PathParam("token") String token, Session session){
            LOGGER.info("长连接已断开,用户:" + token);
            System.out.println("长连接已断开,用户:" + token);
            SESSION_MAP.remove(token);
        }
    
        /**
         * 长连接出现异常
         */
        @OnError
        public void onError(Throwable throwable){
            LOGGER.info("长连接出现异常:" + throwable.getMessage());
            System.out.println("长连接出现异常:" + throwable.getMessage());
        }
    
    
    
    }
    
    
    • 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
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>websocket通讯</title>
    </head>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script>
        var socket;
     
        function openSocket() {
            if (typeof (WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            } else {
                console.log("您的浏览器支持WebSocket");
                //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
                //等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25");
                //var socketUrl="${request.contextPath}/im/"+$("#userId").val();
                //var socketUrl="http://app.boruisijj.com:9099/demo/imserver/"+$("#userId").val();
                var socketUrl = "https://localhost:9093/websocket/" + $("#userId").val();
                socketUrl = socketUrl.replace("https", "wss").replace("http", "ws");
                console.log(socketUrl);
                if (socket != null) {
                    socket.close();
                    socket = null;
                }
                socket = new WebSocket(socketUrl);
                //打开事件
                socket.onopen = function () {
                    console.log("websocket已打开");
                    //socket.send("这是来自客户端的消息" + location.href + new Date());
                };
                //获得消息事件
                socket.onmessage = function (msg) {
                    console.log(msg.data);
                    //发现消息进入    开始处理前端触发逻辑
                };
                //关闭事件
                socket.onclose = function () {
                    console.log("websocket已关闭");
                };
                //发生了错误事件
                socket.onerror = function () {
                    console.log("websocket发生了错误");
                }
            }
        }
     
        function sendMessage() {
            if (typeof (WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            } else {
                console.log("您的浏览器支持WebSocket");
                console.log($("#contentText").val());
                socket.send($("#contentText").val());
            }
        }
    </script>
    <body>
    <p>【userId】:
    <div><input id="userId" name="userId" type="text" value="10"></div>
    <p>【toUserId】:
    <div><input id="toUserId" name="toUserId" type="text" value="20"></div>
    <p>【toUserId】:
    <div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
    <p>【操作】:
    <div><a οnclick="openSocket()">开启socket</a></div>
    <p>【操作】:
    <div><a οnclick="sendMessage()">发送消息</a></div>
    </body>
     
    </html>
    
    • 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
  • 相关阅读:
    分类问题的评价指标
    运行real.exe时出现NUM_METGRID_SOIL_LEVELS=0
    用python实现植物大战僵尸(游戏截图+动态演示+源码分享)
    记一次详细的实战渗透
    shardingsphere 集成springboot【水平分表】
    加密和验签
    免费动态IP代理科普知识课堂—代理服务器的类型
    神经网络全连接层的作用,各种神经网络的优缺点
    【Netty源码系列(二)】解读EventLoopGroup
    JUC总结-基础篇
  • 原文地址:https://blog.csdn.net/qq_40902067/article/details/125421291