# learning
**Repository Path**: Arno_vc/learning
## Basic Information
- **Project Name**: learning
- **Description**: 展示
- **Primary Language**: Java
- **License**: GPL-3.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2022-02-09
- **Last Updated**: 2025-10-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 一、部署流程:
> 为了标识用户,后端需要主动设置用户浏览器的cookie.当前端和后端在同一个项目中——具体表现为共用一个端口,这样做是可行的。但是当我们采用前后端分离的架构,由于浏览器策略的限制(主要为Chrome内核的浏览器),后端返回的Response Head中的set-cookie标识是无法起作用的.解决该问题的方法有多种,比如设置浏览器的配置,通过Ngix进行反向代理,从而使前后端请求接收的端口一致.这里选择了一种较为“简便”的方法,即将前端整合进后端的框架中,最后打包成一个jar包部署即可.由于前端采用vue-cli脚手架,因此我们需要将vue-cli中的内容通过`npm run build`命令进行构建,然后才能把输出目录的内容转移到springboot项目下,进而通过maven的指令打包部署.
## 大致流程
1. vue项目build
2. 将前端内容合并到后端项目(注意不是add)
3. 打包编译
4. 服务器部署
## 具体流程
#### vue项目build
1. 修改shell.vue组件下的ws地址,其地址应为后端的对应接口
2. 修改main.js下的axios.defaults.baseURL地址,该地址为后端所有接口的基地址
3. 修改config目录下的index.js文件下的两处`./`为`/`
4. 在idea的terminal中的输入指令`npm run build`进行打包
打包完成后在项目文件夹下生产一个dist目录,这就是我们对外发布的文件了.dist目录下是index.html和assets文件.
#### 将前端内容合并到后端项目
1. 将前端dist目录下的内容**拖动**放入springboot项目的resource/static目录下(如果原先有东西可以先删除)
#### 打包编译
1. 修改application.yaml中的配置,将test修改为dev
```yaml
spring:
profiles:
active: dev #多环境配置下,选择激活的配置文件
```
2. 点击idea右侧maven/lifecycle中的clean选项清理上次打包的内容,然后再点击package
打包完成后会生成一个target的文件输出目录,目录中的.jar后缀的包的就是我们最终对外发布的内容
#### 服务器部署
> 为了将jar传输到服务器,我们需要ftp工具,然后通过xshell类似的远程终端运行jar包.幸运的是这一系列操作我们可以直接使用idea的相关工具完成
1. 将jar包传输到服务器的指定位置
2. 运行jar包.通常这里还会遇到的一个问题就是端口被上一个版本的项目占用,我们还需要对其进行关闭.这里建议写成一个shell脚本,一键执行即可.
3. 测试
# 二、系统介绍
> 主要包括各子系统的介绍,设计思路,配置参数,以及一些优化的建议
## (一)、用户管理子系统
### 模块介绍
1. 注册模块主要用于学生的注册,同时通过对接阿里云的短信服务完成验证码的发送与绑定,为避免用户的恶意破坏,在阿里云的后台对每月的短信发送量进行了限制.老师的账号权限则直接在数据库设置即可.
2. 登陆模块,包含了账号密码登陆,手机验证登陆,学生及老师登陆等内容
### 要点
1. 尽管注册与登录验证码的发送模板是相同的,但是在session中还是作为2个attribute存放的好——我这里偷了个懒,只用了一个code属性存放.
2. 关于登录接口,对两种不同的登陆参数,通过前端传来的参数loginType作为标识,进而对信息的有效性进行判定
3. 密码使用了mysql中的md5单向加密
### 配置参数
1. 阿里云短信发送的相关配置:application.yaml文件
### 优化建议
1. 添加图片验证以限制DDOS攻击(注意图片要整个从后端的接口过来,而不是在前端生成)
2. 登陆后的跳转——导航栏显示异常
## (二)、主机账号管理子系统
### 介绍
> 主机账号对应的是数据库中hostAccount账号,而非host中的root权限账号.
1. 主机账号分配模块:该模块是整个实验平台的核心,主机账号具有动态性,由后台向终端发起指令进行动态创建.
2. 主机账号删除模块:由**主机账号分配模块**发起的**定时器**调用,用于向终端发起指令进行删除
3. webShell模块:及时的页面终端会话
### 要点
1. webShell
这里的webShell即以网页形式存在的指令控制台,该指令控制台将通过后台与终端相连,并及时地收发指令,这里先简单介绍一下从前端到后端所使用的工具与协议:
* xterm:也就是网页中所呈现的那个黑底白字的指令台,这里使用的就是xterm插件
* webSocket协议:http协议是单工信道的工作模式,只有客户端可以向服务端发起请求,这在使用指令台时是无法满足我们的需求的.例如,当我们通过指令在服务器端设置了一个定时任务后,客户端需要主动地向服务端发送信息.而webSocket协议则稍有所不同,webSocket在传输层同样是基于tcp的,但它所构成的是一个持续连接的双工信道,客户端与服务端可以自由平等地发送信息.
* JSch:一个可以用来远程连接服务器的Java库,对于其使用的形式是相对固定的
以上三块内容从客户端到服务端贯穿了每一条shell指令的执行,而它们之间显然又是独立的,我们要做的将它们**联系**起来,这里我主要也是参考了网上的博客与**相关的demo**.为了便于理解我们从后端向前端讲起:
* 后端接收webSocket请求的过程与http请求类似,http请求需要实现一个Servlet的接口,而webSocket请求实现的则是一个名为WebSocketHandler的接口.在接口中我们根据需要来完成自己的业务,如与建立并保持JSch与服务器的连接,数据操作,接收并处理前端请求,返回后端收到的终端信息等等.值得一提的是JSch的连接需要用一个**线程池**来管理.此外,和http请求一样,我们同样需要一个请求地址,这在继承了`WebSocketConfigurer`接口的registerWebSocketHandlers类中进行配置
* 前端的主要职责是通过webSocket接收后端数据并交给xterm展示,以及接收前端数据发送给后端.这主要是通过new一个WebSocket的内置对象时将其与后端的ws地址绑定,并对其onopen,onmessage,onclose等接口进行实现的方式来完成.接口中对接的则是xterm中的指令.
### 配置参数
1. ws地址,用于前端生成的webSocket对象绑定后端ws地址:前端Shell.vue文件中的`webSocket`地址
2. 主机最大可以分配的用户数目:后端HostDTO类中的`MAX_USER_NUM`属性
3. hostAccount账号有效时间,通过定时器在过期后自动回收:后端ShellTimer类下的`DELAY_TIME`属性
### 优化建议
1. 目前,对于用户输入的每一个字符我们都是直接向后端发送的,显然这在并发量较大的情况下会造成问题,因此建议前端对每个指令以`\r`为标志进行转发
2. shell作为一个独立的页面,可以提供主机ip,端口,用户名,密码的输入
3. 为主机host添加增删改查操作
4. 使shell页面覆盖全屏(不要直接修改div大小,会造成问题,可以翻翻相关的博客,我在调试时相应的插件无法起作用)
## (三)、作业提交子系统
### 介绍
> 由于在初期欠缺规划,该内容是我写的最烂的一部分内容.所以写代码的前提应该是要进行充分的**思考**,其所花费的时间也应该远远大于写代码的时间。
1. 作业创建模块:由老师发起collection的创建,老师也可以在自己的作业集模块下看到具体的作业提交情况
2. 作业提交模块:同学提交作业,提交有两种方式,一种是进行富文本的编辑——其实我觉得一般人都不会这么做,编辑好的内容将以html的形式提交到数据库中存储起来,其中图片上传到阿里云的图床,返回一个地址.第二种形式是文件提交,文件的地址也将被存储在数据库中
3. 作业批改模块:由老师对作业内容进行批改
### 要点
1. 作业的状态:
* 未提交(状态参数:无):未添加作业信息
* 已提交(状态参数:0):添加作业信息
* 完成批改(状态参数:1):批改完成
* 已打回(状态参数:2):作业打回修改
2. 文件上传逻辑:
解释一下:
1. 为什么要修改文件名:避免文件存放在文件夹中时重名
2. 为什么要新建文件:保证上传的文件按日存放以便于管理
3. 图床:所谓图床就是一个专门用来存放图片的服务器.
在使用富文本编辑器进行编辑后,生成的是一个`.html`后缀的内容,该文本最终将存放在数据库中.显然在html中我们的图片存放的一个url,也就是图片上传到**阿里云图床**后的地址.其对接只需要配置前端wangEditor对应的接口即可
### 配置参数
1. 文件上传地址:后端HomeworkServiceImpl类下的fileUpload方法
2. 图床参数配置:前端EditHomework组件下的getEditor方法
### 优化建议
1. 将文件内容做成一张单独的数据表,这样做的好处有三:
* 用户文件上传的作业数将不受限制,可以直接将用户id放置在文件表中(一对多的关系)
* 为了防止重名,所有文件上传后都将生产一个新的名称.单独开一张文件数据表可以存储原文件名以方便下载还原.当然还有一个方法是在现有的homework表中添加原文件名这一数据项,**不推荐**
* 解耦
2. 增加提示信息,效果类似
只需要能够给予用户一定的指引即可(Element-ui应该也有组件可以使用)
* 当老师批改作业后,**学生**可以**收到提示**有作业可以查看
* 当学生提交作业后,**老师**可以**收到提示**有作业需要批改
3. 增加文件上传后的可编辑功能(难度较大),提升两块功能的交互性
## (四)、数据统计模块
### 介绍
> 开始时老师只提出让我记录两个数据的点击率,然后数据统计作为一个模块其实还有极大的可丰富性
目前记录的仅仅是两项数据:操作手册的下载量及仿真操作的获取量
### 要点
无
### 配置参数
无
### 优化建议
1. 修改表结构,目前数据统计的模块仅仅只有一个表记录了所有信息,此时记录的信息量较少.如果分成两个表,一张表记录统计项,另一张表按天记录统计值或许是更为有效的选择
2. 丰富统计数据的表达性:可以在主页通过图表等工具进行信息统计,如前端的EChars,这一块数据的对接总体并不难.
# 三、总括
1. 由于技术,人力,时间及经验的限制,内容的总体完成度并不理想.许多方法没有时间和精力仔细地进行逐一地进行单元测试,也没有特意地去搭建测试环境,但好在基本的技术和功能还是实现了(虽然有些做法是饶了地球半圈..).之后的修改其实目前还没有看到需要复杂的技术支持,但需要仔细(避免犯小错误而给自己找大问题),耐心(可以静心找问题)以及对项目工程有综合性的认识.
2. 关于参数的配置其实上面只提到了一部分.在springBoot项目中,基本的配置文件是application.properties,但是我这里需用的是application.yaml文件,两者的区别主要在于格式.以及由application.yaml衍生出来的配置文件application-dev.yaml和application-test.yaml分别适用于生产环境和测试环境,可以在application.yaml中进行配置.
```yaml
spring:
profiles:
active: dev #多环境配置下,选择激活的配置文件
```
3. 缺少issue模块用于给用户提交反馈
4. 插件:
* 前端:
* vue-router:路由管理
* axios:发送
* xterm:服务器终端显示
* wangeditor:富文本变价
* vueX:状态管理
* qs:用于将js对象格式化为字符串
…
* 后端:
* log4j2:日志(日志实现)
* slf4g:日志门面(日志接口)
* JSch:终端连接
…
5. 后端接口基本逻辑:使用ajaxReturn方法返回数据
* 正确:直接填写数据
* 错误:设置errCode和errMsg
前端接口基本逻辑:
* errCode==200:执行成功的操作
* errCode!=200:打印errMsg
后端错误参数
* 200:成功
* 300:超出资源限制类的错误,非运行错误
* 400:运行错误,通常是对Exception的catch
* 500:权限错误
# 四、问题记录
1. mybatis中的``语法可能无法过滤Integer类型的变量为空的情况
# 五、网站页面






(有服务器情况下可以正常使用)
