SSM框架(四):SSM整合 案例 + 异常处理器 +拦截器

文章目录

  • 一、整合流程图
    • 1.1 Spring整合Mybatis
    • 1.2 Spring整合SpringMVC
  • 二、表现层数据封装
    • 2.1 问题引出
    • 2.2 统一返回结果数据格式 代码设计
  • 三、异常处理器
    • 3.1 概述
    • 3.2 异常处理方案
  • 四、前端
  • 五、拦截器
    • 5.1 概念
    • 5.2 入门案例
    • 5.3 拦截器参数
    • 5.4 拦截器链


一、整合流程图

在这里插入图片描述

1.1 Spring整合Mybatis

在这里插入图片描述

在这里插入图片描述

1.2 Spring整合SpringMVC

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、表现层数据封装

2.1 问题引出

前端人员接收到很多不同数据格式,如下图:
在这里插入图片描述
不便于操作,因此,前端操作人员需要与后端人员统一数据格式
在这里插入图片描述
设计一个统一的数据返回结果类,如下:
在这里插入图片描述

2.2 统一返回结果数据格式 代码设计

Code.java自定义状态码类

package com.itheima.controller;//状态码
public class Code {public static final Integer SAVE_OK = 20011;public static final Integer DELETE_OK = 20021;public static final Integer UPDATE_OK = 20031;public static final Integer GET_OK = 20041;public static final Integer SAVE_ERR = 20010;public static final Integer DELETE_ERR = 20020;public static final Integer UPDATE_ERR = 20030;public static final Integer GET_ERR = 20040;
}

Result.java统一数据返回结果类

package com.itheima.controller;public class Result {//描述统一格式中的数据private Object data;//描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败private Integer code;//描述统一格式中的消息,可选属性private String msg;// 提供不同的构造方法public Result() {}public Result(Integer code,Object data) {this.data = data;this.code = code;}public Result(Integer code, Object data, String msg) {this.data = data;this.code = code;this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}

BookController.java修改controller类,统一返回数据格式

package com.itheima.controller;import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;//统一每一个控制器方法返回值
@RestController
@RequestMapping("/books")
public class BookController {@Autowiredprivate BookService bookService;@PostMappingpublic Result save(@RequestBody Book book) {boolean flag = bookService.save(book);return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);}@PutMappingpublic Result update(@RequestBody Book book) {boolean flag = bookService.update(book);return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);}@DeleteMapping("/{id}")public Result delete(@PathVariable Integer id) {boolean flag = bookService.delete(id);return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);}@GetMapping("/{id}")public Result getById(@PathVariable Integer id) {Book book = bookService.getById(id);Integer code = book != null ? Code.GET_OK : Code.GET_ERR;String msg = book != null ? "" : "数据查询失败,请重试!";return new Result(code,book,msg);}@GetMappingpublic Result getAll() {List<Book> bookList = bookService.getAll();Integer code = bookList != null ? Code.GET_OK : Code.GET_ERR;String msg = bookList != null ? "" : "数据查询失败,请重试!";return new Result(code,bookList,msg);}
}

三、异常处理器

3.1 概述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.2 异常处理方案

在这里插入图片描述
定义异常编码Code.class

package com.itheima.controller;//状态码
public class Code {public static final Integer SAVE_OK = 20011;public static final Integer DELETE_OK = 20021;public static final Integer UPDATE_OK = 20031;public static final Integer GET_OK = 20041;public static final Integer SAVE_ERR = 20010;public static final Integer DELETE_ERR = 20020;public static final Integer UPDATE_ERR = 20030;public static final Integer GET_ERR = 20040;public static final Integer SYSTEM_ERR = 50001;public static final Integer SYSTEM_TIMEOUT_ERR = 50002;public static final Integer SYSTEM_UNKNOW_ERR = 59999;public static final Integer BUSINESS_ERR = 60002;
}

定义业务异常BusinessException.class

package com.itheima.exception;
//自定义异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException{private Integer code;public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public BusinessException(Integer code, String message) {super(message);this.code = code;}public BusinessException(Integer code, String message, Throwable cause) {super(message, cause);this.code = code;}}

定义系统异常SystemExceptionException.class

package com.itheima.exception;//自定义异常处理器,用于封装异常信息,对异常进行分类
public class SystemException extends RuntimeException{private Integer code;public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}// 构造方法public SystemException(Integer code, String message) {super(message);this.code = code;}public SystemException(Integer code, String message, Throwable cause) {super(message, cause);this.code = code;}}

拦截异常并处理SystemExceptionException.class

package com.itheima.controller;import com.itheima.exception.BusinessException;
import com.itheima.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {//@ExceptionHandler用于设置当前处理器类对应的异常类型@ExceptionHandler(SystemException.class)public Result doSystemException(SystemException ex){//记录日志//发送消息给运维//发送邮件给开发人员,ex对象发送给开发人员return new Result(ex.getCode(),null,ex.getMessage());}@ExceptionHandler(BusinessException.class)public Result doBusinessException(BusinessException ex){return new Result(ex.getCode(),null,ex.getMessage());}//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常@ExceptionHandler(Exception.class)public Result doOtherException(Exception ex){//记录日志//发送消息给运维//发送邮件给开发人员,ex对象发送给开发人员return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");}
}

书写异常

package com.itheima.controller;import com.itheima.domain.Book;
import com.itheima.exception.BusinessException;
import com.itheima.exception.SystemException;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;//统一每一个控制器方法返回值
@RestController
@RequestMapping("/books")
public class BookController {@Autowiredprivate BookService bookService;@GetMapping("/{id}")public Result getById(@PathVariable Integer id) {if(id == 1){throw new BusinessException(Code.BUSINESS_ERR,"写错了噢");}try {int i = 1 / 0;}catch(Exception e){throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"访问超时");}Book book = bookService.getById(id);Integer code = book != null ? Code.GET_OK : Code.GET_ERR;String msg = book != null ? "" : "数据查询失败,请重试!";return new Result(code,book,msg);}}

四、前端

编写处理前端路径的配置器SpringMvcSupport.class

package com.itheima.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");registry.addResourceHandler("/css/**").addResourceLocations("/css/");registry.addResourceHandler("/js/**").addResourceLocations("/js/");registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");}
}

前端代码books.html

<!DOCTYPE html><html><head><!-- 页面meta --><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>SpringMVC案例</title><meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"><!-- 引入样式 --><link rel="stylesheet" href="../plugins/elementui/index.css"><link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css"><link rel="stylesheet" href="../css/style.css"></head><body class="hold-transition"><div id="app"><div class="content-header"><h1>图书管理</h1></div><div class="app-container"><div class="box"><div class="filter-container"><el-input placeholder="图书名称" v-model="pagination.queryString" style="width: 200px;" class="filter-item"></el-input><el-button @click="getAll()" class="dalfBut">查询</el-button><el-button type="primary" class="butT" @click="handleCreate()">新建</el-button></div><el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row><el-table-column type="index" align="center" label="序号"></el-table-column><el-table-column prop="type" label="图书类别" align="center"></el-table-column><el-table-column prop="name" label="图书名称" align="center"></el-table-column><el-table-column prop="description" label="描述" align="center"></el-table-column><el-table-column label="操作" align="center"><template slot-scope="scope"><el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button><el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button></template></el-table-column></el-table><!-- 新增标签弹层 --><div class="add-form"><el-dialog title="新增图书" :visible.sync="dialogFormVisible"><el-form ref="dataAddForm" :model="formData" :rules="rules" label-position="right" label-width="100px"><el-row><el-col :span="12"><el-form-item label="图书类别" prop="type"><el-input v-model="formData.type"/></el-form-item></el-col><el-col :span="12"><el-form-item label="图书名称" prop="name"><el-input v-model="formData.name"/></el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="描述"><el-input v-model="formData.description" type="textarea"></el-input></el-form-item></el-col></el-row></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取消</el-button><el-button type="primary" @click="handleAdd()">确定</el-button></div></el-dialog></div><!-- 编辑标签弹层 --><div class="add-form"><el-dialog title="编辑检查项" :visible.sync="dialogFormVisible4Edit"><el-form ref="dataEditForm" :model="formData" :rules="rules" label-position="right" label-width="100px"><el-row><el-col :span="12"><el-form-item label="图书类别" prop="type"><el-input v-model="formData.type"/></el-form-item></el-col><el-col :span="12"><el-form-item label="图书名称" prop="name"><el-input v-model="formData.name"/></el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="描述"><el-input v-model="formData.description" type="textarea"></el-input></el-form-item></el-col></el-row></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible4Edit = false">取消</el-button><el-button type="primary" @click="handleEdit()">确定</el-button></div></el-dialog></div></div></div></div></body><!-- 引入组件库 --><script src="../js/vue.js"></script><script src="../plugins/elementui/index.js"></script><script type="text/javascript" src="../js/jquery.min.js"></script><script src="../js/axios-0.18.0.js"></script><script>var vue = new Vue({el: '#app',data:{pagination: {},dataList: [],//当前页要展示的列表数据formData: {},//表单数据dialogFormVisible: false,//控制表单是否可见dialogFormVisible4Edit:false,//编辑表单是否可见rules: {//校验规则type: [{ required: true, message: '图书类别为必填项', trigger: 'blur' }],name: [{ required: true, message: '图书名称为必填项', trigger: 'blur' }]}},//钩子函数,VUE对象初始化完成后自动执行created() {this.getAll();},methods: {//列表getAll() {//发送ajax请求axios.get("/books").then((res)=>{this.dataList = res.data.data;});},//弹出添加窗口handleCreate() {this.dialogFormVisible = true;this.resetForm();},//重置表单resetForm() {this.formData = {};},//添加handleAdd () {//发送ajax请求axios.post("/books",this.formData).then((res)=>{console.log(res.data);//如果操作成功,关闭弹层,显示数据if(res.data.code == 20011){this.dialogFormVisible = false;this.$message.success("添加成功");}else if(res.data.code == 20010){this.$message.error("添加失败");}else{this.$message.error(res.data.msg);}}).finally(()=>{this.getAll();});},//弹出编辑窗口handleUpdate(row) {// console.log(row);   //row.id 查询条件//查询数据,根据id查询axios.get("/books/"+row.id).then((res)=>{// console.log(res.data.data);if(res.data.code == 20041){//展示弹层,加载数据this.formData = res.data.data;this.dialogFormVisible4Edit = true;}else{this.$message.error(res.data.msg);}});},//编辑handleEdit() {//发送ajax请求axios.put("/books",this.formData).then((res)=>{//将信息打印在控制台上console.log(res.data)//如果操作成功,关闭弹层,显示数据if(res.data.code == 20031){this.dialogFormVisible4Edit = false;this.$message.success("修改成功");}else if(res.data.code == 20030){this.$message.error("修改失败");}else{this.$message.error(res.data.msg);}}).finally(()=>{this.getAll();});},// 删除handleDelete(row) {//1.弹出提示框this.$confirm("此操作永久删除当前数据,是否继续?","提示",{type:'info'}).then(()=>{//2.做删除业务axios.delete("/books/"+row.id).then((res)=>{if(res.data.code == 20021){this.$message.success("删除成功");}else{this.$message.error("删除失败");}}).finally(()=>{this.getAll();});}).catch(()=>{//3.取消删除this.$message.info("取消删除操作");});}}})</script></html>

五、拦截器

5.1 概念

在这里插入图片描述
在这里插入图片描述
拦截器的执行流程
在这里插入图片描述

5.2 入门案例

第一步:声明拦截器的bean,并实现HandlerInterceptor接口,拦截器Intercepter一般放在controller(业务层)包下,需要在类前添加@Component注解。
当preHandle返回值类型可以拦截控制的执行,true放行,false终止。

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {@Override//原始方法调用前执行的内容//返回值类型可以拦截控制的执行,true放行,false终止public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String contentType = request.getHeader("Content-Type");HandlerMethod hm = (HandlerMethod)handler;System.out.println("preHandle..."+contentType);return true;}@Override//原始方法调用后执行的内容public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...");}@Override//原始方法调用完成后执行的内容public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...");}
}

第二步:定义配置类,继承WebMvcConfigurationSupport,实现方法addInterceptors,需要在类前添加@Configuration注解

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {//配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");}
}

第三步:在SpringMvc的配置类前添加@ComponentScan({“com.itheima.controller”,“com.itheima.config”}),以便拦截器ProjectInterceptor和配置类SpringMvcSupport被SpringMvc扫描到。

@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
public class SpringMvcConfig{
}

最后,第二、三步可以合在一起简化开发

@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Autowiredprivate ProjectInterceptor2 projectInterceptor2;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//配置多拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");}
}

5.3 拦截器参数

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5.4 拦截器链

在这里插入图片描述

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

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

相关文章

本科毕业生个人简历23篇

刚毕业的本科生如何制作一份令招聘方印象深刻的简历&#xff1f;可以参考以下这23篇精选的本科毕业生应聘简历案例&#xff01;无论您的专业是什么&#xff0c;都能从中汲取灵感&#xff0c;提升简历质量&#xff0c;轻松斩获心仪职位&#xff01;小伙伴们快来看看吧&#xff0…

C++作业4

代码整理&#xff0c; 将学过的三种运算符重载&#xff0c;每个至少实现一个运算符的重载 代码&#xff1a; #include <iostream>using namespace std;class Stu {friend const Stu operator*(const Stu &L,const Stu &R);friend bool operator<(const Stu …

抓取检测(Grasp Dection)

抓取检测 抓取检测被定义为能够识别任何给定图像中物体的抓取点或抓取姿势。抓取策略应确保对新物体的稳定性、任务兼容性和适应性&#xff0c;抓取质量可通过物体上接触点的位置和手的配置来测量。为了掌握一个新的对象&#xff0c;完成以下任务&#xff0c;有分析方法和经验…

智慧工地一体化解决方案(里程碑管理)源码

智慧工地为管理人员提供及时、高效、优质的远程管理服务&#xff0c;提升安全管理水平&#xff0c;确保施工安全提高施工质量。实现对人、机、料、法、环的全方位实时监控&#xff0c;变被动“监督”为主动“监控”。 一、建设背景 施工现场有数量多、分布广&#xff0c;总部统…

Woocommerce Private Store私人商店秘密商城插件,适合批发商店,会员制俱乐部

点击访问原文Woocommerce Private Store私人商店秘密商城插件&#xff0c;适合批发商店&#xff0c;会员制俱乐部 - 易服客工作室 WooCommerce Private Store插件是使 WooCommerce 私有的简单方法。密码保护您的整个 WooCommerce 商店并使其隐藏。 非常适合批发商店、会员制俱…

面试就是这么简单,offer拿到手软(二)—— 常见65道非技术面试问题

面试系列&#xff1a; 面试就是这么简单&#xff0c;offer拿到手软&#xff08;一&#xff09;—— 常见非技术问题回答思路 面试就是这么简单&#xff0c;offer拿到手软&#xff08;二&#xff09;—— 常见65道非技术面试问题 文章目录 一、前言二、常见65道非技术面试问题…

九、FreeRTOS之FreeRTOS列表和列表项

本节需要掌握以下内容&#xff1a; 1&#xff0c;列表和列表项的简介&#xff08;熟悉&#xff09; 2&#xff0c;列表相关API函数介绍&#xff08;掌握&#xff09; 3&#xff0c;列表项的插入和删除实验&#xff08;掌握&#xff09; 4&#xff0c;课堂总结&#xff08;掌…

L1-012:计算指数

⭐题目描述⭐ 真的没骗你&#xff0c;这道才是简单题 —— 对任意给定的不超过 10 的正整数 n&#xff0c;要求你输出 2n。不难吧&#xff1f; 输入格式&#xff1a; 输入在一行中给出一个不超过 10 的正整数 n。 输出格式&#xff1a; 在一行中按照格式 2^n 计算结果 输出 2n…

Nacos多数据源插件

Nacos从2.2.0版本开始,可通过SPI机制注入多数据源实现插件,并在引入对应数据源实现后,便可在Nacos启动时通过读取application.properties配置文件中spring.datasource.platform配置项选择加载对应多数据源插件.本文档详细介绍一个多数据源插件如何实现以及如何使其生效。 注意:…

c++ day 4

代码整理&#xff0c; 将学过的三种运算符重载&#xff0c;每个至少实现一个运算符的重载:分别是-&#xff0c;-&#xff0c;<。 #include <iostream>using namespace std; class Stu {friend const Stu operator-(const Stu &L,const Stu &R);friend bool o…

当XTS服务遇到切流...

事件回顾 介绍问题前&#xff0c;先介绍两个概念。灰度发布和切流。 灰度发布 灰度发布也叫金丝雀发布。起源是矿井工人发现&#xff0c;金丝雀对瓦斯气体很敏感&#xff0c;矿工会在下井之前&#xff0c;先放一只金丝雀到井中&#xff0c;如果金丝雀不叫了&#xff0c;就代表…

如何获取唐诗三百首中的名句列表接口

唐诗三百首&#xff0c;是中国文学中最为经典的诗歌选集之一&#xff0c;其中涵盖了大量美丽、深刻的诗句&#xff0c;被广泛传诵。有不少文化爱好者希望能够获取这些名句列表&#xff0c;以便深入理解唐诗的内涵和精华。那么&#xff0c;如何获取唐诗三百首中的名句列表呢&…

uniapp运行到安卓基座app/img标签不显示

img是html中的标签&#xff0c;他也是一个单标签 image属于服务器控件&#xff0c;是个双标签 问题&#xff1a;uniapp运行到app安卓基座后图片无法显示 原因&#xff1a;自己使用了img标签&#xff0c;而且输入路径无提示&#xff0c;img标签导致图片不显示 解决&#xff…

深入探索网络协议:揭开互联网运作的奥秘(建议收藏)

随着如今数字化时代的到来&#xff0c;互联网已经成为我们日常生活中不可或缺的一部分。然而&#xff0c;我们是否曾好奇过互联网是如何运作的&#xff1f;它是如何将我们与世界连接起来的&#xff1f;答案就在网络协议中&#xff0c;这是互联网背后的语言。 网络协议的作用和功…

重生奇迹MU再生原石

通过坎特鲁提炼之塔的NPC艾尔菲丝提炼成功就可以可获得再生宝石。 重生奇迹mu里的再生原石的用法&#xff1a; 1、打怪获得再生原石去提炼之塔&#xff08;进入坎特鲁遗址的141188位置的传送台&#xff09;。 2、找到&#xff08;艾儿菲丝&#xff09;把原石提炼成再生宝石。…

【vSphere 8 自签名 VMCA 证书】企业 CA 签名证书替换 vSphere VMCA CA 证书Ⅲ—— 颁发自签名与替换 VMCA 证书

目录 5. 使用 Microsoft 证书颁发机构颁发自签名 CA 证书链5.1 登录MADCS5.2 申请证书5.3 选择证书类型5.4 提交CR5.5 下载 Base 64 编码的证书5.6 将证书链传入VC 6. 使用 企业CA签发的 VMCA 证书 替换 vSphere 默认 VMCA 证书6.1 确认证书文件6.2 替换默认 vSphere 证书6.3 验…

Gateway网关--java

网关是建立于请求到服务之前的,可以用网关限制访问量,添加过滤等 创建网关模块,引入相关pome依赖 配置yml 具体相关的作用可以参考 Spring Cloud Gateway 这样就可以了 基础的网关配置,我们的实现效果 我们可以通过10010端口访问,通过转发到nacos,再找到相应的模块,实现…

CAPL通过ethernetPacket发送以太网报文

文章目录 ethernetPacketCANoe帮助文档车载以太网协议函数CAPL通过ethernetPacket发送以太网报文例子ethernetPacket CANoe中,ethernetPacket类似于CAN的message. CANoe帮助文档 CANoe的帮助文档是很好的学习资料,后面会结合CANoe帮助文档来介绍车载以太网的相关内容。 车…

2023年12月3日支付宝蚂蚁庄园小课堂今日答案是什么?

问题&#xff1a;雪天行车&#xff0c;路面会有不少前车行驶的轨迹&#xff0c;最好&#xff1f; 答案&#xff1a;顺着前车轨迹行驶 解析&#xff1a;雪天路面湿滑&#xff0c;而且可能有冰雪等堆积物遮盖路面&#xff0c;所以&#xff0c;最好顺着前车轨迹减速慢行&#xf…

Asp.Net Core Web Api内存泄漏问题

背景 使用Asp.Net Core Web Api框架开发网站中使用到了tcp socket通信&#xff0c;网站作为服务端开始tcp server&#xff0c;其他的客户端不断高速给它传输信息时&#xff0c;tcp server中读取信息每次申请的byte[]没有得到及时的释放&#xff0c;导致内存浪费越来越多&#…