天马学航——智慧教务系统(移动端)开发日志三

天马学航——智慧教务系统(移动端)开发日志三

日志摘要:更新了学生选课模块、我的课程模块以及退课的功能,优化了后端数据库的缓存

1、学生选课模块

学生选课模块主要实现,学生根据需求进行选课操作,通过后端查询到所有教师的课程,展示在前端,然后根据前端进行选择,选择后发给后端,后端再进行判断,将选课信息返回前端

界面效果
image-20240620111914879
前端源码
struct SelectCourse {@State courses:SCourse[] = []aboutToAppear(){this.getCourse()}build() {Column({ space: 5 }) {Text(" ")Row({ space: 10 }) {Text(" ")Image($r('app.media.back')).width(30).height(30).onClick(function () {//返回上一页router.back() //直接返回})Text("学生选课").fontSize(30).fontWeight(FontWeight.Bolder)}.width('100%')Text("----------------------------------------------")Text(" ")List({space:50}){ForEach(this.courses,course=>{ListItem(){Row({space:30}){Text(" ")Column({space:20}){Text(course.cname).fontColor(Color.Green).fontSize(15).fontWeight(FontWeight.Bolder).fontFamily("楷体")Text("课程号:"+course.cid).fontSize(10).fontColor(Color.Red)Text("任课教师:"+course.tname).fontSize(10).fontColor(Color.Green)}.justifyContent(FlexAlign.Start).alignItems(HorizontalAlign.Start)Blank()Button("选择").onClick(()=>{console.log("学生点击了:"+course.cname)StudentAddCourse.STA(course.cid,course.cname,course.tname).then(resp=>{console.log("前端收到消息!"+resp)promptAction.showToast({message: resp,duration: 2000,bottom: 50});})})}.width('95%').height(150)//.padding(20).backgroundColor(Color.White).borderRadius(15).shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })}})}.width('100%')}.width('100%')}getCourse(){GetCourse.GC().then(resp=>{console.log("请求成功"+resp)if(resp.length === 0){promptAction.showToast({message: '暂无可选课程',duration: 2000,bottom: 50});}this.courses = resp;})}
}
请求源码
请求所有课程部分
class GetCourse {baseURL: string = IP.ipGC(): Promise<SCourse[]> {return new Promise((resolve, reject) => {let Http = http.createHttp()Http.request(`${this.baseURL}/GCourse`,{method: http.RequestMethod.GET,connectTimeout: 10000,readTimeout: 10000}).then(resp=>{if(resp.responseCode === 200){console.log("请求成功"+resp.result)resolve(JSON.parse(resp.result.toString()))}else {console.log("请求发现异常"+resp.responseCode)}}).catch(error=>{console.log("请求失败")})})}
}const gc = new GetCourse()
export default gc as GetCourse
向后端发送选课结果部分
class StudentAddCourse{baseURL: string = IP.ipSTA(cid:string,cname:string,cteacher:string):Promise<string>{const data = {cid:cid,cname:cname,cteacher:cteacher}return new Promise((resolve, reject) => {let httpRequest = http.createHttp()httpRequest.request(`${this.baseURL}/StuSelectcourse`,{method:http.RequestMethod.GET,extraData:data,connectTimeout: 10000,readTimeout:10000},).then(resp=>{if(resp.responseCode === 200){console.log("请求成功:"+resp.result)resolve(resp.result.toString())}else {console.log("请求失败:"+resp.responseCode)}}).catch(error=>{console.log("检查链接!")})})}
}const aa = new StudentAddCourse()
export default aa as StudentAddCourse
后端源码
请求所有课程部分
public class getCourse extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json");resp.setCharacterEncoding("UTF-8");//MybatisSqlSession sql = MybatisUntills.getSqlSession();CourseMapper mapper = sql.getMapper(CourseMapper.class);List<SelectCourse> allCourse = mapper.getAllCourse();//执行并返回数据for (SelectCourse selectCourse : allCourse) {System.out.println(selectCourse.getCid()+selectCourse.getCname()+selectCourse.getTname());}sql.close();//打包Gson gson = new Gson();String JsonData = gson.toJson(allCourse);//发送resp.getWriter().write(JsonData);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
接收学生选课信息部分
public class StuSelectCourse extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json");resp.setCharacterEncoding("UTF-8");ServletContext c = getServletContext();HttpSession session = req.getSession();String username = (String) session.getAttribute("username");if(username == null){username = (String) c.getAttribute("username");}String cid = req.getParameter("cid");String cname = req.getParameter("cname");String ct = req.getParameter("cteacher");System.out.println("课程号"+cid);//MybatisSqlSession sql = MybatisUntills.getSqlSession();CourseMapper mapper = sql.getMapper(CourseMapper.class);Map<String,Object> map1 = new HashMap<String, Object>();map1.put("cid",cid);map1.put("sid",username);String strings = mapper.showStudentCourse(map1);if(strings!=null){resp.getWriter().write("后端返回信息:该课程已存在!");sql.close();}else {Map<String,Object> map = new HashMap<String, Object>();map.put("cid",cid);map.put("sid",username);int i = mapper.addStudentCourse(map);sql.commit();if(i==1){resp.getWriter().write("后端返回信息:选课成功!");System.out.println("成!");}else {resp.getWriter().write("后端返回信息:选课失败!");}sql.close();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

2、我的课程(退课模块)

主要显示该用户选择的所有课程,并提供退课的选项,后端查询,前端显示,前端选择,后端判断,将信息返回前端

界面效果
image-20240620111914879
前端源码
struct MyCourse{@State courses:StudentMyCourse[] = []aboutToAppear(){this.MyCourses()}build() {Column({ space: 5 }) {Text(" ")Row({ space: 10 }) {Text(" ")Image($r('app.media.back')).width(30).height(30).onClick(function () {//返回上一页router.back() //直接返回})Text("我的课程").fontSize(30).fontWeight(FontWeight.Bolder)}.width('100%')Text("----------------------------------------------")Text(" ")List({space:50}){ForEach(this.courses,course=>{ListItem(){Row({space:30}){Text(" ")Column({space:20}){Text(course.cname).fontColor(Color.Green).fontSize(15).fontWeight(FontWeight.Bolder).fontFamily("楷体")Text("课程号:"+course.cid).fontSize(10).fontColor(Color.Red)Text("任课教师:"+course.tname).fontSize(10).fontColor(Color.Green)Text("上课时间:"+course.ctime).fontSize(10).fontColor(Color.Green)}.justifyContent(FlexAlign.Start).alignItems(HorizontalAlign.Start)Blank()Button("退课").backgroundColor(Color.Red).onClick(()=>{console.log("学生点击了:"+course.cname)DeletCourse.STA(course.cname,course.cid,course.tname,course.ctime).then(resp=>{console.log("返回成功"+resp)promptAction.showToast({message: resp,duration: 2000,bottom: 50});})})}.width('95%').height(150)//.padding(20).backgroundColor(Color.White).borderRadius(15).shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })}})}.width('100%')}}MyCourses(){GetStudentCourse.GC().then(resp=>{console.log("返回信息成功"+resp.toString())if(resp.length === 0){promptAction.showToast({message: '您还没有选课哦~',duration: 2000,bottom: 50});}this.courses = resp})}
}
请求源码
请求所选课程
class GetStudentCourse {baseURL: string = IP.ipGC(): Promise<StudentMyCourse[]> {return new Promise((resolve, reject) => {let Http = http.createHttp()Http.request(`${this.baseURL}/GetMyCourse`,{method: http.RequestMethod.GET,connectTimeout: 10000,readTimeout: 10000}).then(resp => {if (resp.responseCode === 200) {console.log("请求成功" + resp.result)resolve(JSON.parse(resp.result.toString()))}else {console.log("请求成功,但是出现问题" + resp.responseCode)}}).catch(error => {console.log("请求失败" + error)})})}
}const sc = new GetStudentCourse()
export default sc as GetStudentCourse
向后端发送退课信息
class DeletCourse {baseURL: string = IP.ipSTA(cname: string, cid: string, tname: string,ctime: string): Promise<string> {const data = {cname: cname,cid: cid,tname: tname,ctime:ctime}return new Promise((resolve, reject) => {let httpRequest = http.createHttp()httpRequest.request(`${this.baseURL}/DeletMyCourse`,{method: http.RequestMethod.GET,extraData: data,connectTimeout: 10000,readTimeout: 10000},).then(resp=>{if(resp.responseCode===200){console.log("请求成功!"+resp.result)resolve(resp.result.toString())}else {console.log("请求发生错误"+resp.responseCode)}}).catch(err=>{console.log("请求失败"+err)})})}
}const sc = new DeletCourse()
export default sc as DeletCourse

后端代码与选课部分相同,这里不再赘述

3、BUG修复

修复了Mybatis二级缓存溢出导致查询变慢的问题

天马学航——智慧教务系统(移动端)开发日志二

日志摘要:更新了学生选课模块、我的课程模块以及退课的功能,优化了后端数据库的缓存

1、学生选课模块

学生选课模块主要实现,学生根据需求进行选课操作,通过后端查询到所有教师的课程,展示在前端,然后根据前端进行选择,选择后发给后端,后端再进行判断,将选课信息返回前端

界面效果
image-20240620111914879
前端源码
struct SelectCourse {@State courses:SCourse[] = []aboutToAppear(){this.getCourse()}build() {Column({ space: 5 }) {Text(" ")Row({ space: 10 }) {Text(" ")Image($r('app.media.back')).width(30).height(30).onClick(function () {//返回上一页router.back() //直接返回})Text("学生选课").fontSize(30).fontWeight(FontWeight.Bolder)}.width('100%')Text("----------------------------------------------")Text(" ")List({space:50}){ForEach(this.courses,course=>{ListItem(){Row({space:30}){Text(" ")Column({space:20}){Text(course.cname).fontColor(Color.Green).fontSize(15).fontWeight(FontWeight.Bolder).fontFamily("楷体")Text("课程号:"+course.cid).fontSize(10).fontColor(Color.Red)Text("任课教师:"+course.tname).fontSize(10).fontColor(Color.Green)}.justifyContent(FlexAlign.Start).alignItems(HorizontalAlign.Start)Blank()Button("选择").onClick(()=>{console.log("学生点击了:"+course.cname)StudentAddCourse.STA(course.cid,course.cname,course.tname).then(resp=>{console.log("前端收到消息!"+resp)promptAction.showToast({message: resp,duration: 2000,bottom: 50});})})}.width('95%').height(150)//.padding(20).backgroundColor(Color.White).borderRadius(15).shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })}})}.width('100%')}.width('100%')}getCourse(){GetCourse.GC().then(resp=>{console.log("请求成功"+resp)if(resp.length === 0){promptAction.showToast({message: '暂无可选课程',duration: 2000,bottom: 50});}this.courses = resp;})}
}
请求源码
请求所有课程部分
class GetCourse {baseURL: string = IP.ipGC(): Promise<SCourse[]> {return new Promise((resolve, reject) => {let Http = http.createHttp()Http.request(`${this.baseURL}/GCourse`,{method: http.RequestMethod.GET,connectTimeout: 10000,readTimeout: 10000}).then(resp=>{if(resp.responseCode === 200){console.log("请求成功"+resp.result)resolve(JSON.parse(resp.result.toString()))}else {console.log("请求发现异常"+resp.responseCode)}}).catch(error=>{console.log("请求失败")})})}
}const gc = new GetCourse()
export default gc as GetCourse
向后端发送选课结果部分
class StudentAddCourse{baseURL: string = IP.ipSTA(cid:string,cname:string,cteacher:string):Promise<string>{const data = {cid:cid,cname:cname,cteacher:cteacher}return new Promise((resolve, reject) => {let httpRequest = http.createHttp()httpRequest.request(`${this.baseURL}/StuSelectcourse`,{method:http.RequestMethod.GET,extraData:data,connectTimeout: 10000,readTimeout:10000},).then(resp=>{if(resp.responseCode === 200){console.log("请求成功:"+resp.result)resolve(resp.result.toString())}else {console.log("请求失败:"+resp.responseCode)}}).catch(error=>{console.log("检查链接!")})})}
}const aa = new StudentAddCourse()
export default aa as StudentAddCourse
后端源码
请求所有课程部分
public class getCourse extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json");resp.setCharacterEncoding("UTF-8");//MybatisSqlSession sql = MybatisUntills.getSqlSession();CourseMapper mapper = sql.getMapper(CourseMapper.class);List<SelectCourse> allCourse = mapper.getAllCourse();//执行并返回数据for (SelectCourse selectCourse : allCourse) {System.out.println(selectCourse.getCid()+selectCourse.getCname()+selectCourse.getTname());}sql.close();//打包Gson gson = new Gson();String JsonData = gson.toJson(allCourse);//发送resp.getWriter().write(JsonData);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
接收学生选课信息部分
public class StuSelectCourse extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json");resp.setCharacterEncoding("UTF-8");ServletContext c = getServletContext();HttpSession session = req.getSession();String username = (String) session.getAttribute("username");if(username == null){username = (String) c.getAttribute("username");}String cid = req.getParameter("cid");String cname = req.getParameter("cname");String ct = req.getParameter("cteacher");System.out.println("课程号"+cid);//MybatisSqlSession sql = MybatisUntills.getSqlSession();CourseMapper mapper = sql.getMapper(CourseMapper.class);Map<String,Object> map1 = new HashMap<String, Object>();map1.put("cid",cid);map1.put("sid",username);String strings = mapper.showStudentCourse(map1);if(strings!=null){resp.getWriter().write("后端返回信息:该课程已存在!");sql.close();}else {Map<String,Object> map = new HashMap<String, Object>();map.put("cid",cid);map.put("sid",username);int i = mapper.addStudentCourse(map);sql.commit();if(i==1){resp.getWriter().write("后端返回信息:选课成功!");System.out.println("成!");}else {resp.getWriter().write("后端返回信息:选课失败!");}sql.close();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

2、我的课程(退课模块)

主要显示该用户选择的所有课程,并提供退课的选项,后端查询,前端显示,前端选择,后端判断,将信息返回前端

界面效果
image-20240620111914879
前端源码
struct MyCourse{@State courses:StudentMyCourse[] = []aboutToAppear(){this.MyCourses()}build() {Column({ space: 5 }) {Text(" ")Row({ space: 10 }) {Text(" ")Image($r('app.media.back')).width(30).height(30).onClick(function () {//返回上一页router.back() //直接返回})Text("我的课程").fontSize(30).fontWeight(FontWeight.Bolder)}.width('100%')Text("----------------------------------------------")Text(" ")List({space:50}){ForEach(this.courses,course=>{ListItem(){Row({space:30}){Text(" ")Column({space:20}){Text(course.cname).fontColor(Color.Green).fontSize(15).fontWeight(FontWeight.Bolder).fontFamily("楷体")Text("课程号:"+course.cid).fontSize(10).fontColor(Color.Red)Text("任课教师:"+course.tname).fontSize(10).fontColor(Color.Green)Text("上课时间:"+course.ctime).fontSize(10).fontColor(Color.Green)}.justifyContent(FlexAlign.Start).alignItems(HorizontalAlign.Start)Blank()Button("退课").backgroundColor(Color.Red).onClick(()=>{console.log("学生点击了:"+course.cname)DeletCourse.STA(course.cname,course.cid,course.tname,course.ctime).then(resp=>{console.log("返回成功"+resp)promptAction.showToast({message: resp,duration: 2000,bottom: 50});})})}.width('95%').height(150)//.padding(20).backgroundColor(Color.White).borderRadius(15).shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })}})}.width('100%')}}MyCourses(){GetStudentCourse.GC().then(resp=>{console.log("返回信息成功"+resp.toString())if(resp.length === 0){promptAction.showToast({message: '您还没有选课哦~',duration: 2000,bottom: 50});}this.courses = resp})}
}
请求源码
请求所选课程
class GetStudentCourse {baseURL: string = IP.ipGC(): Promise<StudentMyCourse[]> {return new Promise((resolve, reject) => {let Http = http.createHttp()Http.request(`${this.baseURL}/GetMyCourse`,{method: http.RequestMethod.GET,connectTimeout: 10000,readTimeout: 10000}).then(resp => {if (resp.responseCode === 200) {console.log("请求成功" + resp.result)resolve(JSON.parse(resp.result.toString()))}else {console.log("请求成功,但是出现问题" + resp.responseCode)}}).catch(error => {console.log("请求失败" + error)})})}
}const sc = new GetStudentCourse()
export default sc as GetStudentCourse
向后端发送退课信息
class DeletCourse {baseURL: string = IP.ipSTA(cname: string, cid: string, tname: string,ctime: string): Promise<string> {const data = {cname: cname,cid: cid,tname: tname,ctime:ctime}return new Promise((resolve, reject) => {let httpRequest = http.createHttp()httpRequest.request(`${this.baseURL}/DeletMyCourse`,{method: http.RequestMethod.GET,extraData: data,connectTimeout: 10000,readTimeout: 10000},).then(resp=>{if(resp.responseCode===200){console.log("请求成功!"+resp.result)resolve(resp.result.toString())}else {console.log("请求发生错误"+resp.responseCode)}}).catch(err=>{console.log("请求失败"+err)})})}
}const sc = new DeletCourse()
export default sc as DeletCourse

后端代码与选课部分相同,这里不再赘述

3、BUG修复

修复了Mybatis二级缓存溢出导致查询变慢的问题

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

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

相关文章

Java学习 - 网络IP地址与子网划分 讲解

IP地址 作用 用于决定数据包最终到达哪个计算机 组成 由32位比特组成&#xff0c;即4个字节这32位可以分为两个部分&#xff0c;称为网络号和主机号同一网段的计算机网络号相同&#xff0c;路由器负责连接不同的网段&#xff0c;而交换机负责连接同一网段中不同的计算机同一…

如何将 ChatGPT 集成到你的应用中

在当今快速发展的技术环境中&#xff0c;将人工智能聊天解决方案集成到你的应用程序中可以显著提升用户体验和参与度。OpenAI 的 ChatGPT 以其对话能力和高级语言理解而闻名&#xff0c;对于希望在其应用程序中实现智能聊天功能的开发人员来说是一个绝佳的选择。那我们今天就来…

高性能并行计算华为云实验一:MPI矩阵运算

目录 一、实验目的 二、实验说明 三、实验过程 3.1 创建矩阵乘法源码 3.1.1 实验说明 3.1.2 实验步骤 3.2 创建卷积和池化操作源码 3.2.1 实验说明 3.2.2 实验步骤 3.3 创建Makefile文件并完成编译 3.4 建立主机配置文件与运行监测 四、实验结果与分析 4.1 矩阵乘法…

压缩包文件密码破解软件 Ziperello 下载及使用教程

使用 Ziperello https://qweree.cn/index.php/416/ 对加了密码的压缩包进行密码破解&#xff0c;教程如下&#xff1a; 第一步&#xff0c;双击运行 Ziperello双击我打开程序.exe&#xff0c;如下图&#xff1a; 第二步&#xff0c;打开一个加了密的 ZIP 压缩包&#xff0c;再…

什么概率密度函数?

首先我们来理解一下什么是连续的随机变量&#xff0c;在此之前&#xff0c;我们要先理解什么是随机变量。所谓随机变量就是在一次随机实验中一组可能的值。比如说抛硬币&#xff0c;我们设正面100&#xff0c;反面200&#xff0c;设随机变量为X&#xff0c;那么X{100,200}。 X是…

STM32学习笔记(十)--I2C、IIC总线协议详解

概述&#xff1a;Inter Integrated Circuit&#xff0c;一组多从 多组多从 有应答 是一种同步&#xff08;具有时钟线需要同步时钟SCL&#xff09;、串行&#xff08;一位一位的往一个方向发送&#xff09;、半双工&#xff08;发送接收存在一种&#xff09;通信总线。 &…

【调试笔记-20240618-Windows-pnpm 更新出现 Cannot find module 问题的解决方法】

调试笔记-系列文章目录 调试笔记-20240618-Windows-pnpm 更新出现 Cannot find module 问题的解决方法 文章目录 调试笔记-系列文章目录调试笔记-20240618-Windows-pnpm 更新出现 Cannot find module 问题的解决方法 前言一、调试环境操作系统&#xff1a;Windows 10 专业版调…

qmt量化交易策略小白学习笔记第46期【qmt编程之期货行情数据--如何获取5档盘口行情、期货结算价与持仓量】

qmt编程之获取期货数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;咨询免费开通量化回测与获取实盘权限&#xff0c;欢迎和博主联系&#xff01; 获取5档盘口行情 …

GeoJson 地图地理信息数据获取

效果图&#xff1a; 获取渠道&#xff1a; 通过阿里数据可视化平台获取通过Vector Maps获取通过geojson来获取 1、通过阿里数据可视化平台获取 2、通过Vector Maps获取 3、通过geojson获取

数据通信与网络(五)

交换机功能&#xff1a; 地址学习&#xff08;端口/MAC地址映射表&#xff09; 通信过滤&#xff08;基于端口/MAC地址映射表&#xff09; 生成树协议&#xff08;断开环路&#xff09; 隔离冲突域 生成树协议 隔离冲突域 交换机配置模式(用不同级别的命令对交换机进行配置) 普…

如何一步一步将Python中的应用打包成安卓的APK安装包文件

一、首先&#xff0c;按照如下链接操作 Python 应用打包成 APK【全流程】_python打包成apk-CSDN博客 二、运行 buildozer init会报错buildozer命令找不到&#xff0c;明明已经安装 解决方法&#xff1a; 这里重新创建一个conda环境 Installation — Buildozer 0.11 docum…

Oracle基本语法(SQLPlus)

目录&#xff1a; 前言&#xff1a; 准备工作&#xff1a; 登录&#xff1a; 1.打开SQL Plus命令行工具 第一种方式&#xff1a; 第二种方式&#xff1a; 2.以不同用户登录 SYSTEM&#xff08;普通管理员&#xff09;&#xff1a; SYS(超级管理员)&#xff1a; 不显示…

408计算机组成原理

todo:有逻辑的分门别类的整理笔记&#xff0c;方便复习 总 理解不了就直接背下来&#xff0c;学越多就越能理解 计算机系统概述 简要目录 基本概念 字长 MAR MDR PC IR CU ALU 通用寄存器、标志寄存器、标志控制器 ACC 地址译码器 通用寄存器 PU C语言编译过程 数据通路带…

DAY10-力扣刷题

1.最后一个单词的长度(简单) 58. 最后一个单词的长度 - 力扣&#xff08;LeetCode&#xff09; 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子…

Unity3d自定义TCP消息替代UNet实现网络连接

以前使用UNet实现网络连接,Unity2018以后被弃用了。要将以前的老程序升到高版本,最开始打算使用Mirro,结果发现并不好用。那就只能自己写连接了。 1.TCP消息结构 (1). TCP消息是按流传输的,会发生粘包。那么在发射和接收消息时就需要对消息进行打包和解包。如果接收的消息…

Nutch爬虫在大数据采集中的应用案例

引言 在当今信息爆炸的时代&#xff0c;大数据的价值日益凸显。网络作为信息的海洋&#xff0c;蕴藏着丰富的数据资源。Nutch&#xff0c;作为一个开源的Java编写的网络爬虫框架&#xff0c;以其高效的数据采集能力和良好的可扩展性&#xff0c;成为大数据采集的重要工具。本文…

Mac安装多个jdk环境(jdk8+jdk17)保姆级

Mac安装多个jdk环境&#xff08;jdk8jdk17&#xff09;保姆级 背景&#xff1a;新机安装开发环境发现需要找很多文章&#xff0c;&#xff0c;&#xff0c;&#xff0c;这里一篇文章安装所有环境 文章目录 Mac安装多个jdk环境&#xff08;jdk8jdk17&#xff09;保姆级&#x1f…

C语言入门系列:指针入门(超详细)

文章目录 一&#xff0c;什么是指针1&#xff0c;内存2&#xff0c;指针是什么&#xff1f; 二&#xff0c;指针的声明1&#xff0c;声明指针类型变量2&#xff0c;二级指针 三&#xff0c;指针的计算1&#xff0c;两个指针运算符1.1 *运算符1.2 & 运算符1.3 &运算符与…

【Arthas案例】应用包含两个相同全限定类名StaticLoggerBinder,引起log4j.Level类找不到异常

3分钟内解决问题 两个不同的GAV依赖冲突&#xff0c;包含相同全限定类名&#xff0c;引起ClassNotFoundException Maven依赖的三坐标体系GAV(G-groupId&#xff0c;A-artifactId&#xff0c;V-version) 【案例1】某应用依赖两个GAV不同的jar&#xff0c;但包含两个相同全限定类…

OpenCv形态学(一)

目录 形态学转换 结构元素 腐蚀 膨胀 开运算 闭运算 形态学梯度 顶帽 黑帽 图像轮廓 查找轮廓 绘制轮廓 形态学转换 形态变换是一些基于图像形状的简单操作。通常在二值图像上执行。它需要两个输入&#xff0c;一个是我们的原始图像&#xff0c;第二个是决定操作性…