WebSocket Day03 : SpringMVC整合WebSocket

前言

在现代Web应用程序中,实时性和即时通信变得越来越重要。传统的HTTP请求-响应模式无法满足实时数据传输和双向通信的需求。随着技术的发展,WebSocket成为了一种强大而灵活的解决方案。 WebSocket是HTML5提供的一种新的通信协议,它通过一个持久化的、双向的连接,在客户端和服务器之间实现了实时的数据传输和双向通信。相比传统的HTTP请求-响应模式,WebSocket能够提供更低的延迟、更高的效率和更好的用户体验。 本文是“WebSocket 教程”系列的第三篇,将介绍如何将WebSocket与SpringMVC框架整合起来,以实现基于WebSocket的实时通信功能。我们将使用SpringMVC作为Web应用程序的基础框架,利用其强大的功能和易用的开发模式,结合WebSocket的优势,构建一个实时通信的应用程序。

一、WebSocket和SpringMVC的基本概念和原理

WebSocket是HTML5提供的一种通信协议,它允许在客户端和服务器之间建立一个持久化的、双向的连接,实现实时的数据传输和双向通信。相比传统的HTTP请求-响应模式,WebSocket具有以下特点:

  1. 双向通信:WebSocket允许客户端和服务器之间进行双向通信,而不仅仅是单向的请求-响应模式。这意味着服务器可以主动发送消息给客户端,而不需要客户端发起请求。

  2. 持久连接:一旦WebSocket连接建立成功,它将保持持久性的连接状态,不像HTTP请求-响应模式那样需要在每次请求后关闭连接。这样可以减少因频繁建立和关闭连接而产生的额外开销。

  3. 低延迟:由于WebSocket使用了长连接,数据传输的延迟相对较低。这使得实时性要求高的应用场景,如聊天应用、股票行情等,能够更好地满足用户的需求。

SpringMVC是一个基于Java的开源MVC(Model-View-Controller)框架,用于构建Web应用程序。它提供了强大的功能和灵活的开发模式,使得开发者可以轻松构建可扩展、可维护的Web应用程序。在整合WebSocket时,SpringMVC提供了对WebSocket的支持,简化了WebSocket的使用和管理。

SpringMVC框架中与WebSocket相关的几个核心概念包括:

  1. WebSocketHandler:WebSocketHandler是一个处理WebSocket连接和消息的接口,开发者需要实现该接口来处理不同类型的WebSocket消息。

  2. WebSocketSession:WebSocketSession代表一个WebSocket连接,它提供了一些方法来发送消息、关闭连接等操作。

  3. WebSocketConfigurer:WebSocketConfigurer是一个配置接口,用于配置WebSocket相关的参数和处理器。

  4. @EnableWebSocket:@EnableWebSocket注解用于启用WebSocket支持,将WebSocketConfigurer实例注册到SpringMVC的配置中。

通过使用SpringMVC提供的WebSocket支持,我们可以更方便地使用WebSocket,并且与SpringMVC的其他功能进行无缝整合。这使得开发者能够更加高效地构建实时通信的Web应用程

二、前期准备

1、新建项目,结构如下

2、导入依赖
<!-- websocket 依赖 --><dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version><scope>provided</scope></dependency><!-- 打印日志 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.3.8</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><!-- ch03 --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.23</version></dependency><!-- 在 spring 4.0 开始支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId><version>5.3.23</version></dependency>

 这些依赖项在Spring MVC项目中具有以下用途:

  1. javax.websocket-api:这个依赖项提供了WebSocket API的规范,包括用于创建和管理WebSocket连接的接口和类。它是WebSocket开发的基本依赖项。

  2. logback-classic:这是Logback日志框架的经典模块,用于记录应用程序的日志。它可以在开发过程中帮助调试和跟踪问题。

  3. lombok:Lombok是一个Java库,通过注解的方式简化了Java代码的编写。它提供了各种实用的注解,如@Data、@Getter、@Setter等,可以减少样板代码的编写。

  4. spring-webmvc:这是Spring MVC框架的核心模块,提供了处理Web请求的基本功能,包括控制器、视图解析器、数据绑定等。

  5. spring-websocket:这是Spring框架提供的WebSocket支持模块。它为Spring MVC应用程序启用了WebSocket功能,包括配置和管理WebSocket连接、处理WebSocket消息等。

以上是这些依赖项的常见用途。通过添加这些依赖项,您可以在Spring MVC项目中使用WebSocket,并处理来自客户端的实时消息。

三、在SpringMVC中配置和启用WebSocket支持 

 1、WebSocket 配置类

@Configuration
// 启用 WebSocket 支持
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {/*** 装配服务端* @return*/@Beanpublic WebSocketHandler webSocketHandler(){return new ChatServer();}/*** 装配 HttpSession 的拦截器,这样就可以在握手阶段* 获取 HttpSession 的内容,在使用 WebSocketSession 时* 就能直接得到 HttpSession 的数据* @return*/@Beanpublic HandshakeInterceptor handshakeInterceptor(){return new HttpSessionHandshakeInterceptor();}/*** 给服务端注册请求的端点(映射连接地址)* @param registry*/@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {// 给 CharServer 设置连接的 urlregistry.addHandler(webSocketHandler(), "/connect")// 设置握手拦截器.addInterceptors(handshakeInterceptor());}
}

WebSocket的配置类,用于启用WebSocket支持并配置WebSocket相关的参数。

首先,我们使用@Configuration注解将该类标记为配置类。

然后,我们使用@EnableWebSocket注解启用WebSocket支持。

接下来,我们实现WebSocketConfigurer接口,并实现其中的方法。

registerWebSocketHandlers()方法中,我们通过registry.addHandler()方法注册一个WebSocket处理器(ChatServer)并指定连接的URL为"/connect"。同时,我们通过addInterceptors()方法添加一个握手拦截器(HttpSessionHandshakeInterceptor),这样就可以在握手阶段获取HttpSession的内容。

最后,我们使用@Bean注解分别装配了ChatServerHttpSessionHandshakeInterceptor的实例,并将其返回。

2、MvcConfig 配置类
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {@Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();}
}

MVC的配置类,用于启用Spring MVC并配置默认的Servlet处理。

首先,我们使用@Configuration注解将该类标记为配置类。

然后,我们使用@EnableWebMvc注解启用Spring MVC支持。

接下来,我们实现了WebMvcConfigurer接口,并重写了其中的configureDefaultServletHandling()方法。

configureDefaultServletHandling()方法中,我们通过调用configurer.enable()方法启用默认的Servlet处理。这意味着将会使用Servlet容器提供的默认Servlet来处理静态资源,而不是通过DispatcherServlet来处理。

通常情况下,Spring MVC会使用DispatcherServlet作为前端控制器,负责处理所有的请求和响应。但有时候我们可能希望使用Servlet容器提供的默认Servlet来处理一些静态资源,例如图片、样式表和JavaScript文件等。通过调用configurer.enable()方法,我们可以启用默认的Servlet处理来处理这些静态资源。

3、AppConfig 配置类
@Configuration
@ComponentScan(basePackages = "edu.nf.ch03")
@Import({MvcConfig.class,WebSocketConfig.class})
public class AppConfig {
}

 首先,我们使用@Configuration注解将该类标记为配置类。

然后,我们使用@ComponentScan注解指定要扫描的基础包路径为edu.nf.ch03。这意味着Spring将会自动扫描该包及其子包下的所有组件,例如控制器、服务类、存储库等,并进行相应的装配和管理。

接下来,我们使用@Import注解导入了两个配置类:MvcConfigWebSocketConfig。通过将其他配置类导入到当前配置类中,可以实现不同配置之间的组合和共享。

最后,我们定义了一个AppConfig类作为整个应用的配置入口点。

4、WebConfig 配置类
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[0];}@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{AppConfig.class};}@Overrideprotected String[] getServletMappings() {return new String[]{"/"};}
}

 这段代码是一个Web应用的配置类,用于初始化DispatcherServlet并指定配置类和URL映射。

首先,我们定义了一个名为WebConfig的类,并继承自AbstractAnnotationConfigDispatcherServletInitializer类。这是Spring提供的一个方便的初始化器类,用于在Java配置中使用注解配置DispatcherServlet。

然后,我们重写了getRootConfigClasses()方法,返回一个空数组。这意味着我们不需要在根应用上下文中加载其他的配置类,因为我们已经在getServletConfigClasses()方法中指定了要加载的配置类。

接下来,我们重写了getServletConfigClasses()方法,返回一个包含AppConfig.class的数组。这样就指定了要在DispatcherServlet的应用上下文中加载的配置类,即AppConfig

最后,我们重写了getServletMappings()方法,返回一个包含"/"的字符串数组。这样就指定了DispatcherServlet的URL映射为根路径/,表示所有请求都会被DispatcherServlet处理。

四、实现登录

1、新建 controller ,实现登录

@Controller
public class UserController {/*** 简单的用户登录* @param userName* @param session* @return*/@PostMapping("/user/login")public String login(String userName, HttpSession session){// 将用户信息保存到会话作用域session.setAttribute("user",userName);// 重定向到聊天的首页return "redirect:/static/chat.html";}}

这是一个基于Spring MVC的控制器类,用于处理用户登录请求。该类包含了一个login方法,该方法通过@PostMapping注解将请求映射到/user/login路径。

参数说明:

  • userName:表示用户输入的用户名。
  • session:表示HttpSession对象,用于保存用户信息。

方法逻辑:

  1. 将用户信息保存到会话作用域中,使用session.setAttribute("user", userName),其中"user"是属性名,userName是属性值。
  2. 通过返回"redirect:/static/chat.html"实现重定向到聊天首页。

总结:该login方法实现了用户登录的逻辑,并将用户信息保存到会话中,然后重定向到聊天首页。在实际应用中,需要进一步处理用户登录的验证、错误处理等逻辑。

 2、新建一个登录页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>用户登录</h1>
<form name="f1" method="post" action="../user/login">
Name:<input type="text" name="userName"/>
<input type="submit" value="登录">
</form>
</body>
</html>

该页面包含了以下元素:

  1. <form>:HTML表单,用于向服务器端发送请求。
    • name="f1":表单的名称,用于JavaScript访问。
    • method="post":使用POST方法提交请求。
    • action="../user/login":指定表单提交的目标地址,即UserController类中的login方法的映射路径。
  2. <input type="text" name="userName"/>:用于输入用户名的文本框。
    • type="text":指定输入框的类型为文本框。
    • name="userName":指定输入框的名称,用于后台获取用户输入的用户名。
  3. <input type="submit" value="登录">:用于提交表单的按钮。
    • type="submit":指定按钮的类型为提交按钮。
    • value="登录":指定按钮上的文本为“登录”。

五、实现服务端发送信息

1、新建一个消息对象 Message

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message {private String fromUser;private String sendTime;private String content;}
 2、实现服务端聊天

public class ChatServer extends TextWebSocketHandler {/*** 用户列表* 每一个用户连接时都会创建一个 WebSocket 对象*/private static final Map<String, WebSocketSession> users = new HashMap<>();/*** 客户端建立连接后执行的方法,等效于 onOpen 方法* @param session* @throws Exception*/@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {// 获取登录的用户信息String userName = (String) session.getAttributes().get("user");// 保存到用户列表users.put(userName,session);}/*** 接受客户端的消息,等效于 onMessage 方法* @param session* @param message* @throws Exception*/@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// 获取消息载体,也就是客户端发送的文本内容String msgContent = message.getPayload();// 获取发送人String fromUser = (String) session.getAttributes().get("user");// 发送时间String sendTime = new SimpleDateFormat("hh:mm").format(new Date());// 封装消息对象Message msg = new Message(fromUser,sendTime,msgContent);// 序列化为 JSON 字符串String json = new ObjectMapper().writeValueAsString(msg);// 群发给所有人for( String userName : users.keySet()){WebSocketSession s = users.get(userName);// 发送消息,必须是一个 TextMessage 的对象s.sendMessage(new TextMessage(json));}}/*** 连接关闭后执行的方法* @param session* @param status* @throws Exception*/@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {String userName = (String) session.getAttributes().get("user");// 将用户移除在线列表users.remove(userName);}
}

这是一个简单的聊天服务器的示例代码,使用WebSocket来实现客户端之间的即时通信。让我们逐行解析这段代码的功能和实现细节:

  1. Map<String, WebSocketSession> users:用于保存用户列表,每个用户连接时都会创建一个WebSocketSession对象。

  2. afterConnectionEstablished方法:在客户端与服务器建立连接后执行的方法。它从WebSocketSession中获取登录的用户信息,并将其保存到用户列表中。

  3. handleTextMessage方法:接收客户端发送的消息并进行处理。它从WebSocketSession中获取消息内容和发送人信息,然后封装成一个Message对象,并将其序列化为JSON字符串。接着,它通过遍历用户列表,将消息发送给所有在线用户。

  4. afterConnectionClosed方法:在客户端与服务器断开连接后执行的方法。它从WebSocketSession中获取断开连接的用户信息,并将其从用户列表中移除。

以上就是这段代码的主要功能和实现逻辑。需要注意的是,这只是一个简单的示例,实际的聊天服务器可能还需要处理更多的业务逻辑和异常情况。此外,这段代码使用了Spring框架提供的TextWebSocketHandler类,你需要确保正确地配置Spring WebSocket相关的依赖和配置文件。

3、新建聊天页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/JQuery文件.txt.js"></script>
</head>
<body>
<h1>聊天室</h1>
<div id="msg"><input type="text" id="message"/><input type="button" value="发送"/><br></div><script>// 创建 WebSocket 对象var ws = new WebSocket("ws://localhost:8080/connect");// 接受服务端的信息ws.onmessage = function (event) {// 将消息填充到 div 中let data = event.data;// 将 json 字符串 转换为 json 对象data = $.parseJSON(data);$('#msg').append(data.fromUser + " : " + data.sendTime + "<br>");$('#msg').append(data.content + "<br>");}$(function () {$(':button').on('click',function () {let msg = $('#message').val();// 发送消息ws.send(msg);// 发送完之后清空消息框$('#message').val('');})})</script></body>
</html>

这是一个简单的聊天室的前端代码示例。让我们逐行解析这段代码的功能和实现细节:

  1. <div id="msg">:消息显示区域。

  2. <input type="text" id="message"/>:文本输入框,用于输入发送的消息内容。

  3. <input type="button" value="发送"/><br>:发送按钮。

  4. <script>:JavaScript脚本区域。

  5. var ws = new WebSocket("ws://localhost:8080/connect");:创建WebSocket对象,连接到服务器的地址是"ws://localhost:8080/connect"。

  6. ws.onmessage:监听WebSocket对象的onmessage事件,当接收到来自服务器的消息时执行相应的操作。

  7. let data = event.data;:获取接收到的消息数据。

  8. data = $.parseJSON(data);:将接收到的JSON字符串转换为JSON对象。

  9. $('#msg').append(data.fromUser + " : " + data.sendTime + "<br>");:将发送人和发送时间添加到消息显示区域。

  10. $('#msg').append(data.content + "<br>");:将消息内容添加到消息显示区域。

  11. $('button').on('click',function () {...}):监听发送按钮的点击事件。

  12. let msg = $('#message').val();:获取文本输入框中的消息内容。

  13. ws.send(msg);:通过WebSocket对象发送消息到服务器。

  14. $('#message').val('');:发送完消息后清空文本输入框。

以上就是这段前端代码的主要功能和实现逻辑。需要注意的是,这个示例代码使用了jQuery库来简化DOM操作和事件处理。你需要确保正确地引入jQuery库,并根据自己的实际情况修改WebSocket连接地址和其他相关代码。

 

 4、运行效果

六、gitee案例

地址:ch03 · qiuqiu/WebSocket-study - 码云 - 开源中国 (gitee.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132494.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaEE的渊源

JavaEE的渊源 1. JavaEE的起源2. JavaEE与Spring的诞生3. JavaEE发展历程&#xff08;2003-2007&#xff09;4. JavaEE发展历程&#xff08;2009-至今&#xff09;5. Java的Spec数目与网络结构 1. JavaEE的起源 我们首先来讲一下JavaEE的起源 ,为什么要来讲起源 &#xff1f; …

Unit1_3:分治算法之排序问题

文章目录 一、归并排序二、快速排序思路伪代码流程图时间复杂度改进 三、堆排序结构插入提取最小值排序抽象 四、比较排序总结决策树模型 一、归并排序 归并排序子操作的思路和Unit1_2逆序计算一样 下面写一下伪代码 if left < right thencenter←L(left right)/2];Merge…

使用 Clipdrop 替换长安三万里电影海报中的天空

长安三万里是一部不久前上映的古装动画电影&#xff0c;讲述了李白和高适的故事。电影海报中的天空是一片晴朗的月空&#xff0c;与扬州城的景色相得益彰。 最近&#xff0c;我发现了一款名为 Clipdrop 的软件&#xff0c;可以用来替换图片中的天空。这款软件使用人工智能技术&…

MyBatis缓存详解

1. MyBatis缓存 MyBatis中的缓存是用来提高性能&#xff0c;减少数据库交互次数的机制。它分为一级缓存&#xff08;Local Cache&#xff09;和二级缓存&#xff08;Global Cache&#xff09;。 1.1 一级缓存&#xff08;Local Cache&#xff09; 作用范围&#xff1a;一级缓…

深入了解汽车级功率MOSFET NVMFS2D3P04M8LT1G P沟道数据表

汽车级功率MOSFET是一种专门用于汽车电子领域的功率MOSFET。它具有高电压、高电流、高温、高可靠性等特点&#xff0c;能够满足汽车电子领域对功率器件的严格要求。汽车级功率MOSFET广泛应用于汽车电机驱动、泵电机控制、车身控制等方面&#xff0c;能够提高汽车电子系统的效率…

Flume从入门到精通一站式学习笔记

文章目录 什么是FlumeFlume的特性Flume高级应用场景Flume的三大核心组件Source&#xff1a;数据源channelsink Flume安装部署Flume的使用案例&#xff1a;采集文件内容上传至HDFS案例&#xff1a;采集网站日志上传至HDFS 各种自定义组件例如&#xff1a;自定义source例如&#…

【RtpSeqNumOnlyRefFinder】webrtc m98: ManageFrameInternal 的帧决策过程分析

Jitterbuffer(FrameBuffer)需要组帧以后GOP内的参考关系 JeffreyLau 大神分析 了组帧原理而参考关系(RtpFrameReferenceFinder)的生成伴随了帧决策 FrameDecisionFrameDecision 影响力 帧的缓存。调用 OnAssembledFrame 传递已经拿到的RtpFrameObject 那么,RtpFrameObject…

安全性在外卖系统开发中的重要性

外卖系统的开发需要强调安全性&#xff0c;因为系统中涉及用户的个人信息、支付信息以及交易数据。确保这些信息的安全对于用户信任和系统的成功至关重要。以下是在外卖系统开发中提升安全性的一些建议。 数据加密 用户信息和支付数据应该经过加密处理。对于敏感信息&#x…

计算机的主存储器与辅助存储器

文章目录 前言一、主存储器&#xff08;内存&#xff09;1.主存储器特征2.主存储器构成3.主存储器和CPU如何交互4.主存储器和操作系统位数的关系 二、辅助存储器&#xff08;磁盘&#xff09;1.辅助存储器构成2.辅助存储器特征3.磁盘的调度算法3.1先来先服务算法3.2最短寻道时间…

错误:ERROR Cannot read properties of null (reading ‘type‘)

ERROR Cannot read properties of null (reading ‘type’) TypeError: Cannot read properties of null (reading ‘type’) <template><el-card><el-row :gutter"20" class"header"><el-col :span"7"><el-input pl…

大厂面试题-innoDB如何解决幻读

从三个方面来回答&#xff1a; 1、Mysql的事务隔离级别 Mysql有四种事务隔离级别&#xff0c;这四种隔离级别代表当存在多个事务并发冲突时&#xff0c;可能出现的脏读、不可重复读、幻读的问题。 其中InnoDB在RR的隔离级别下&#xff0c;解决了幻读的问题。 2、什么是幻读&…

Java前后端分离的在线考试系统源码

Java前后端分离的在线考试系统源码 技术栈 1&#xff0c;SpringBoot 2&#xff0c;Mybatis-plus 3&#xff0c;MySQL 5.7 4&#xff0c;Vue全家桶 5&#xff0c;ElementUI 6&#xff0c;Redis 7&#xff0c;Swagger 8&#xff0c;阿里云OSS 9&#xff0c;Log4j 考…

2023 electron最新最简版windows、mac打包、自动升级详解

这里我将讲解一下从0搭建一个electron最简版架子&#xff0c;以及如何实现打包自动化更新 之前我有写过两篇文章关于electron框架概述以及 常用api的使用&#xff0c;感兴趣的同学可以看看 Electron桌面应用开发 Electron桌面应用开发2 搭建electron 官方文档&#xff1a;ht…

Temu新规定强制要求卖家上传英代、欧代信息——站斧浏览器

根据官方消息&#xff1a;自10月15日起&#xff0c;Temu要求所有在欧洲站点销售的电子产品包装标识上都要加上英代和欧代信息&#xff0c;否则产品可能会被拒收。因此&#xff0c;欧洲站的卖家要抓紧时间完成欧代、英代合规&#xff0c;以免造成损失。 同时&#xff0c;近日Tem…

uboot启动linux kernel的流程

目录 前言流程图autoboot_commandrun_command_listdo_bootmdo_bootm_statesdo_bootm_linuxboot_prep_linuxboot_jump_linux 前言 本文在u-boot启动流程分析这篇文章的基础上&#xff0c;简要梳理uboot启动linux kernel的流程。 流程图 其中&#xff0c; autoboot_command位于…

苹果Mac电脑fcpx视频剪辑:Final Cut Pro中文最新 for mac

Final Cut Pro是苹果公司开发的一款专业视频剪辑软件&#xff0c;它为原生64位软件&#xff0c;基于Cocoa编写&#xff0c;支持多路多核心处理器&#xff0c;支持GPU加速&#xff0c;支持后台渲染。Final Cut Pro在Mac OS平台上运行&#xff0c;适用于进行后期制作。 Final Cu…

应用场景 | 中小河流治理监测系统,提升流域智能感知能力

当前&#xff0c;受全球气候变化和人类活动影响&#xff0c;我国中小河流洪涝灾害呈多发、频发趋势&#xff0c;中小河流洪水已成为严重威胁人民群众生命财产安全的重大风险隐患。中小河流治理作为一项重要的民生水利任务&#xff0c;近十年来国家不断加大以防洪为主的治理投入…

预处理、编译、汇编、链接

1.预处理 宏替换去注释引入头文件 2.编译 3.汇编 4.链接 gcc 基于C/C的编译器 补充说明 gcc命令 使用GNU推出的基于C/C的编译器&#xff0c;是开放源代码领域应用最广泛的编译器&#xff0c;具有功能强大&#xff0c;编译代码支持性能优化等特点。现在很多程序员都应用…

2023数学建模国赛C题赛后总结

今天国赛的成绩终于出来了&#xff0c;盼星星盼月亮的。之前面试的时候已经把我给推到国奖评委那里去了&#xff0c;可是好可惜&#xff0c;最终以很微小的劣势错失国二。只拿到了广西区的省一。我心里还是很遗憾的&#xff0c;我真的为此准备了很久&#xff0c;虽然当中也有着…

如何对非线性【SVM】进行三维可视化

首先导入相应的模块&#xff0c; from sklearn.datasets import make_blobs from sklearn.svm import SVC import matplotlib.pyplot as plt import numpy as np 我们使用make_circles()函数创建散点图&#xff0c;并将散点图中的点的横纵坐标赋值给x,y&#xff0c;其中x是特…