目录
- 一、完善
- 二、项目打包
- 三、部署
- 四、报错解决
- 五、数据初始
一、完善
- 系统管理员数据维护模块功能完善
- 优化教学组织名称的输入提示补全
- 数据对应格式bug修复
1.系统管理员数据维护模块功能完善
系统管理员可以对数据进行维护,例如添加学院、添加导入基层教学组织名称(为了规范用户输入的数据格式,提示补全输入内容)
实现思路就是一般的增,点击增加学院按钮、教学组织名称按钮,将输入的学院、教学组织名称传入后端进行保存
其中需要注意的地方:
- Restful风格或者一般的RequestBody请求方式,是无法将中文字符传入后端的,因为中文字符 会 变成乱码,后端取不出来,干脆直接在后端创建对应实体,将 学院名称、基层教学组织名称、批量导入的基层教学组织名称数组 作为 属性,进而逐个处理
- 异步请求和 填入对话框内容的清空 需要有先后顺序,默认的循序是 清空先执行(执行的速度快),携带表单数据的请求在后面,导致传入的数据为
""
,解决办法就是将 清空对话框数据的 语句放到 请求成功 之后。 - 对于批量添加后端的处理,MongodbTemplate并没有批量添加内嵌数组数据的方法,采用的是循环逐个添加
2.优化教学组织名称的输入提示补全
为了输入数据格式的控制,规范教学组织名称,需要加上 内容下拉提示补全 功能,在输入的时候,下方下拉框显示匹配的 完整内容
主要的就是前端的实现,大致实现逻辑
<el-col :span="7">
<el-form-item class="el-form-item_label" label="教学组织名称">
<el-autocomplete
style="width: 250px"
v-model="form.info.organization"
:fetch-suggestions="querySearch"
placeholder="请输入内容"
:trigger-on-focus="false"
@select="handleSelect"
></el-autocomplete>
</el-form-item>
</el-col>
data() {
return {
//基层组织列表,从后端拿数据
arrayOfGrassRootsTeachingSystemName: [
// {
// value: 'aaa'
// },
// {
// value: 'bbb'
// },
// {
// value: 'ccc'
// },
// {
// value: 'csccc'
// }
]
....
....
}
}
// 方法
//显示搜索内容
handleSelect(item) {
console.log(item);
},
//基层教学组织输入框查找相关输入内容
querySearch(queryString, cb) {
var arrayOfGrassRootsTeachingSystemName = this
.arrayOfGrassRootsTeachingSystemName;
var results = queryString
? arrayOfGrassRootsTeachingSystemName.filter(
this.createFilter(queryString)
)
: arrayOfGrassRootsTeachingSystemName;
// 调用 callback 返回建议列表的数据
cb(results);
},
//过滤出相关输入内容
createFilter(queryString) {
return (arrayOfGrassRootsTeachingSystemName) => {
return (
arrayOfGrassRootsTeachingSystemName.value
.toLowerCase()
.indexOf(queryString.toLowerCase()) !== -1
);
};
},
二、项目打包
1.前端项目打包
前后端分离的项目部署方式很多种,可以使用多个服务器部署,也可以前后端放在一起部署,这里我就一块部署
设置好生产环境的url,前端执行 npm run build:prod
,生成dist目录,将里面二段内容复制(不含dist文件夹)放在后端的resource/static
目录
其中打包的过程遇到控制台报错,参考解决:Vue解决报错8_打包时TyeError: Class extends value undefined is not a constructor or null
然后开启后端测试
2.后端项目打包
因为前后端是放在一起的,直接打成jar包就行,使用mvn 的packge命令
最终在target目录下生成 jar文件,稍后直接ftp到服务器,配置完相关环境后就可以运行
三、部署
准备一台服务器,使用xShell连接,接着就是服务器环境的配置
这里需要注意的是,阿里云的ecs服务器好像没有ftp服务,使用8Uftp一直连接不上去,为了上传文件,推荐使用xShell
参考:SpringBoot项目部署到阿里云linux服务器全流程
3.1安装jdk11及环境配置
下载jdk11 的linux版tar包,官网下载很慢,自行选择
链接:https://pan.baidu.com/s/1yCObT1mCQWuTpXSS60YMOg
提取码:nsk9
复制这段内容后打开百度网盘手机App,操作更方便哦
之后ssh连接服务器
-
执行
yum install lrzsz
-
创建文件夹,执行
rz
选中文件上传至服务器,速度可能会比较慢
-
执行
tar -zxvf xxx.tar.gz
解压jdk文件 -
配置jdk环境变量
找到文件 /etc/profile ,向其中添加如下代码:
export JAVA_HOME=/usr/java/你安装的jdk名称 export CLASSPATH=$JAVA_HOME/lib/ export PATH=$PATH:$JAVA_HOME/bin export PATH JAVA_HOME CLASSPATH
然后执行
source /etc/profile
使配置生效
3.2配置MongoDB环境
大致步骤:
-
下载mongodb:执行
wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.9.tgz
,然后解压 -
创建db、log文件夹,mongod.conf配置文件,编辑配置文件
-
尝试启动:
/usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongo --dbpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/db --logpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/log/mongodb.log --fork
-
重新绑定ip和配置文件:
/usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongod --dbpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/db --logpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/log/mongodb.log --bind_ip 172.25.204.157 -f /usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongodb.conf
-
设置开机自启:
vi /etc/rc.d/rc.local
,然后将 上一步的代码复制 添加保存即可 -
测试启动:
/usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongo 172.25.204.157
提示:这里的版本是2.4.9,springboot可能对于mongodb的版本又要求,选择合适的版本进行安装使用,这里我安装的版本就太低,需要重新安装更高的版本,详情见下文。
3.3配置Radis环境
主要是配合shiro做session的缓存
大致步骤:
- 下载、解压、编译安装
- 测试启动redis:在当前的 /usr/local/redis-4.0.6/src 目录下启动,
./redis-server
,这种需要页面一直打开,需要配置服务后台开启 - 以后台进程方式启动redis
- 设置redis开机自启动
- 启动redis:
service redisd start
3.4上传jar包
java jar xxx.jar
运行,需要一直打开命令行,后台进程运行 nohup java jar xxx.jar
查看进程 ps -ef | grep java
是否正常开启
测试访问xxxx:8080,注意需要打开设置安全组策略开启系列服务端口
四、报错解决
1报错解决
测试发现登录页面能显示,但是登录不进去,检查redis和mongodb的服务都开启了,而且服务器客户端都能正常打开访问
然后配置文件也看了一遍应该没问题,检查不出来。
1.1只好在本机测试,现在本机测试mongodb,使用本机连接服务器的mongodb
开始一直连接不上,后来发现 安全组策略没放行,加上27017测试,能访问得到了,但是又报了错
1.2服务器mongodb版本太低
err:Server at 47.108.148.53:27017 reports wire version 0, but this version of the driver requires at least 2 (MongoDB 2.6).; nested exception is com.mongodb.MongoIncompatibleDriverException: Server at 47.108.148.53:27017 reports wire version 0, but this version of the driver requires at least 2 (MongoDB 2.6).
解决的话就是 删除旧的版本,重新安装新的版本
-
下载:
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.6.4.tgz
-
解压安装:
tar -zxvf mongodb-linux-x86_64-rhel62-3.6.4.tgz
-
移动:
mv mongodb-linux-x86_64-rhel62-3.6.4/ /usr/local/mongodb
-
系统profile配置:
vi /etc/profile
,加上环境变量
export MONGODB_HOME=/usr/local/mongodb
export PATH=$PATH:$MONGODB_HOME/bin
-
重启系统配置:
source /etc/profile
-
mongodb启动配置
// 第一步 cd /usr/local/mongodb/bin // 第二步 vi mongodb.conf // 下面内容添加到配置文件 dbpath = /usr/local/mongodb/data/db #数据文件存放目录 logpath = /usr/local/mongodb/logs/mongodb.log #日志文件存放目录 port = 27017 #端口 fork = true #以守护程序的方式启用,即在后台运行 #nohttpinterface = true #先注释掉 有的版本不需要 加上反而启不来 报错
-
启动mongodb
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/bin/mongodb.conf
发现报错
1.2.1注意配置文件一定要写好,空格也需要注意,这个就是dbpath后面加了一个空格报错
1.2.1配置文件格式正确后,还是无法启动,报错
about to fork child process, waiting until server is ready for connections.
forked process: 1620
ERROR: child process failed, exited with error number 1
To see additional information in this output, start without the "--fork" option.
原因是 logpath配置的 logs/mongodb.log文件还没创建
2.redis连接失败解决
上述redis的配置基本完成,以为没什么问题,运行web系统
MongoDB应该是没什么问题了
但是一直跑不起来,开始找错…
- 本地windows的项目跑起来,打开redis,然后竟然服务器端和本地都能跑了,关掉本地idea开发环境,只打开redis却不行,推测出是服务器的redis有问题
- 改springboot的application.yaml配置文件的redis的host,没什么用
- 修改redis的配置文件,改bind的ip 为 0.0.0.0,保护模式为no,一系列操作发现远程能连接redis了,但是项目就是跑不起来
- 卸载redis,准备使用yum进行安装,但是yum不能用,只好去官网下载tar包,然后rz到服务器(这里我总结三点…),然后又重装了一个6.0.2版本最新的redis,然后老一套配置
- …
快奔溃的时候,我通过浏览器控制台点进去失败的请求,发现地址栏显示 localhost:8080/user/login
前端忘记改地址了(明明记得改过了,可能是忘记保存了…),然后改好地址(不要忘记加8080端口号!!!),重新打包、rz,运行
这次终于不是network error
,而且token已经生成了,证明redis没什么大问题了,而是又报了一个500服务端的错(终于跳出了大坑,可喜可贺可口可乐~)
服务端报错,说redis需要密码,springboot里面已经设置过密码了
详细报错信息
Mar 30, 2021 12:42:52 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.] with root cause
redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.
at redis.clients.jedis.Protocol.processError(Protocol.java:132)
at redis.clients.jedis.Protocol.process(Protocol.java:166)
at redis.clients.jedis.Protocol.read(Protocol.java:220)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:278)
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:196)
at redis.clients.jedis.BinaryJedis.set(BinaryJedis.java:226)
at org.crazycake.shiro.WorkAloneRedisManager.set(WorkAloneRedisManager.java:73)
at org.crazycake.shiro.RedisSessionDAO.saveSession(RedisSessionDAO.java:73)
at org.crazycake.shiro.RedisSessionDAO.doCreate(RedisSessionDAO.java:124)
at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.create(AbstractSessionDAO.java:116)
at org.apache.shiro.session.mgt.DefaultSessionManager.create(DefaultSessionManager.java:177)
at org.apache.shiro.session.mgt.DefaultSessionManager.doCreateSession(DefaultSessionManager.java:158)
at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.createSession(AbstractValidatingSessionManager.java:136)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.start(AbstractNativeSessionManager.java:99)
at org.apache.shiro.mgt.SessionsSecurityManager.start(SessionsSecurityManager.java:152)
at org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:340)
at org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:316)
at org.apache.shiro.mgt.DefaultSubjectDAO.mergePrincipals(DefaultSubjectDAO.java:207)
at org.apache.shiro.mgt.DefaultSubjectDAO.saveToSession(DefaultSubjectDAO.java:165)
at org.apache.shiro.mgt.DefaultSubjectDAO.save(DefaultSubjectDAO.java:146)
at org.apache.shiro.mgt.DefaultSecurityManager.save(DefaultSecurityManager.java:387)
at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:354)
at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:187)
at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:287)
at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
at org.apache.shiro.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:53)
at henu.soft.xiaosi.shiro.ShiroFilter.onAccessDenied(ShiroFilter.java:91)
at org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(AccessControlFilter.java:133)
at org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162)
at org.apache.shiro.web.filter.PathMatchingFilter.isFilterChainContinued(PathMatchingFilter.java:203)
at org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:178)
at henu.soft.xiaosi.shiro.ShiroFilter.preHandle(ShiroFilter.java:56)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
干脆直接改bind 127.0.0.1,发现requirepass前面有个空格,删去试试
发现还是不行,既然设置了bind 127.0.0.1,直接取消密码
终终终于能跑起来了,心累。
五、数据初始
mongodb的部分数据初始,后端需要调整更新mongodb自动生成ObjectId 对应的 service 里面的业务逻辑 表id(因为不同机器的ObjectId是不同的,而且时间戳也不同)
- 学院表college
- 角色表role
- 基层教学组织名称表organization_name
- …
其实可以单独设置一个字段来作为动态生成的ObjectId,可以方便部署,不过多次部署的情况好像也并不需要,方便这来吧。