一.后端java
1.代码生成器:
- 遇到报错
Class not found: "com.example.service2.CodeGenerator"
,我自己查出的原因是由于CodeGenerator这个代码生成器所在module的命名也是service2,与com.example.service2包有重名部分,修改service2为其他名即可。
2.破解IDEA:
- 经过自己体验,最奇葩的破解问题在于破解包jetbrains-agent已经安装完毕,同时也根据教程配置在了正确位置,也在IDEA中的help->Edit Custom VM Options中配置了
-javaagent:D:\IDEA\IntelliJ IDEA 2019.3.2\bin\jetbrains-agent.jar
,即这个破解包的安装位置,但结果是不能重启IDEA。经历千辛万苦,通过everything的搜索,我找到了问题是出在有多个与jetbrains-agent同名的类似文件,可能是由于多次配置失败的缘故遗留下来的。把这些多余的文件全部删去,只保留jetbrains-agent安装包,就解决了问题。我还发现虽然我下载的这个安装包命名不带jar,但是搜出来是自动带上了,所以不需要重命名加上jar,当然也可能是我擅自加上了jar,导致了问题出现。
3.swagger配置:
创建了swagger配置类,并且在启动类上注解了配置类的路径后,对于在pom文件中引用不同模块依赖不成功的情况下,可以在project structure中进行添加模块依赖。(本人在IDEA2019.3.2上的结论)
4.创建多层子模块:
例如一个父模块是module,其中一个子模块是module1,要想在该子模块中再new出一个子模块,需要先删除module的src文件夹,否则module1的new中不会出现module选项,但并没有解决实质性问题,还是有问题。
5.无法下载jar包:
下载未成功:当下载未成功时,千万别急着立马重新下载,当然刷新让它下载是可能有用的,但如果没用,就应该先去本地仓库删掉第一次下载的jar包,因为不管你第一次下载成没成功,是否下错了,都会记录下来到本地仓库,然后你又直接下载,则会默认直接从本地仓库中引用,自然一错再错。
6.运行controller:
两个同时显示的错误"message": "nested exception is org.apache.ibatis.reflection.ReflectionException
与javax.net.ssl.SSLException MESSAGE: closing inbound before receiving peer’s close_notify
,通过关闭SSL验证,即在jdbc的配置里将url加属性useSSL=false
具体如:`jdbc:mysql://192.168.0.19:3306/db1?useSSL=false
7.主键生成策略:
遇到报错org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Could not set property 'id' of 'class com.example.eduService.entity.EduTeacher' with va
,可能是主键生成策略错误,例如:
以上为正确实例,需注意的是红框内为ID_WORKER_STR时,使用在字符串上;为ID_WORKER时,使用在数字类型如long上。
8.前端页面加载异常
提示执行全局异常处理,说明后端代码出现问题
9.项目中创建mapper接口出现问题
- 错误提示:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.eduService.mapper.EduCourseMapper.getPublishCourseInfo
- 原因:
1.mapper中的方法名与实际方法名不一致等问题。
2.maven默认加载机制:把java文件夹中的java类型文件编译后在target中,但xml文件却不会被编译到target中,则执行mapper接口去找配置xml文件时就找不到。 - 解决方式:
1.复制xml到target目录中;
2.把xml文件放到resources目录中;
3.推荐使用:通过配置实现
(1)pom.xml:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
//**指代多级目录
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
(2)项目application.yml:
mybatis-plus:
mapper-locations: classpath:com/example/eduService/mapper/xml/*.xml
//特别注意mapper-locations:与classpath之间空一格
10.视频点播异常(阿里云视频点播)
- 异常信息:
Exception in thread "main" com.aliyuncs.exceptions.ClientException: InvalidVideo.NoneStream : The video has no stream to play for the request parameter ''. RequestId : 86C6E135-68AA-47B8-A928-BAD7780D
- 异常解决:出错是由于视频格式是.wmv,将这个格式转换成.mp4或重新选择一个新的.mp4格式的视频。
11.上传视频文件大小限制异常
- 异常信息:
Caused by: java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.
- 异常解决:配置文件设置上传文件大小如下
#最大上传单个文件大小:默认1M
spring.servlet.multipart.max-request-size=1024MB
#最大总上传的数据大小:默认10M
spring.servlet.multipart.max-file-size=1024MB
12.添加redis缓存功能后引起的问题
- 1.异常描述:
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'selectEightList' cannot be found on object of type 'org.springframework.cache.interceptor.CacheExpressionRootObject' - maybe not public or not valid?
- 1.解决:注解中的key值除了加双引号,还要在里面再加一对单引号。
- 2.如果已经完成了redis缓存功能的相关代码,则应该注意在启动项目前开启redis服务,否则也会报错,进而造成加载页面有问题。
13.注意登录密码问题
- 由于一般登录密码存放在数据库中都是加密后的形式,故用方法判断输入的登录密码和数据库中的登录密码是否一致时,应该先对输入的密码进行加密后再比较。
14.@RequestBody与@xxMapping
- 异常原因:方法参数中注解为@RequestBody,方法注解为@GetMapping。
- 异常说明:
org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.example.commonUtils.R com.example.educenter.controller.UcenterMemberController.loginUser(com.example.educenter.entity.UcenterMember)
- 异常解决:将方法上的注解@GetMapping换成@PostMapping。
二.数据库
1.mysql8.0密码:
首先需要明白对于这个版本的一些命令有些不同,比如跳过密码登录命令为mysqld --console --skip-grant-tables --shared-memory
,然后需要注意在修改root用户密码时的命令update user set authentication_string="修改密码" where user="root"
,被坑的就是修改密码那里,因为查看一些其他教程是说用password(“修改密码”)。(再次强调这是针对8.0版本)
三.前端vue
1.知识细节
1.1 babel转码器:
如果出现'babel' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
,显然是要配置babel的环境变量,注意是添加它的安装路径,只需要具体到npm这个层级就可以,例如我配置的C:\Users\86155\AppData\Roaming\npm
,不要以为什么都配成到bin。
1.2 路由切换:
- created注意点:vue-router导航切换时,如果两个路由都渲染同一个组件,组件会重用,组件的生命周期钩子created不会再被调用,使得组件一些数据无法根据path变换得到更新。例如:
这两张图是两个不同的路由渲染了同一个组件,即点击修改按钮和点击添加讲师都会进入同一个页面,区别是添加是这个页面没有数据回显,修改会回显数据。虽然在created中进行了条件判断区分,但在这两个路由之间切换却达不到区分效果(修改回显,添加置空)。说明由于是进入的同一个页面,created只进行一次操作。
- watch监听:能够解决第一个路由切换问题,其格式为:
watch:{
$route(to,from){//路由变化,该方法会执行
.....
}
}
1.3 403报错:
原因:
- 跨域 (本人使用了主键crossorigin,详情地址:crossorigin详解)
- 路径错误
1.4 视频上传没效果:
- nginx原因1:由于视频上传在分布式开发中属于新的模块,故而要配置新的端口,在nginx的conf文件中配置跳转端口。如下:
- nginx原因2:nginx支持上传大小有限制,所以要在其配置文件中添加如下:
1.5 nuxt配置vue-awesome-swiper
注意点(坑): nuxt版本为2.0.0,swiper版本为4.5.1,vue-awesome-swiper 为3.1.3。(swiper与vue-awesome-swiper存在对应关系)
- 下载指定版本格式如下:(可能出现下载vue-awesome-swiper时自动安装了swiper,但可能版本不对。nuxt,是wiper,vue-awesome-swiper这三个都可以打开它们目录下的package.json查看)
npm install vue-awesome-swiper@xxx(版本号) --save -dev
npm install swiper@xxx(版本号) --save -dev
- nuxt的plugins下创建配置文件nuxt-swiper-plugin.js,内容如下:(可以原样复制)
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper/dist/ssr'// 导入swiper所有css样式
import 'swiper/dist/css/swiper.css'
Vue.use(VueAwesomeSwiper)
- nuxt的nuxt.config.js文件添加内容如下:注意plugins里的src路径是上一步配置文件的路径。
css: [
{ src: "swiper/dist/css/swiper.css" }
],
plugins: [
{ src: "~/plugins/nuxt-swiper-plugin.js", ssr: false },
],
1.6 前端JSON与后端字符串
- 在前端获取到后端数据是字符串形式,想要取出其中数据,需要先转换成JSON形式,代码如下:
JSON.parse(xxx)//括号中为字符串数据
1.7 页面原样输出前端代码
- 错误示例说明:
<p>{{courseWebVo.description}}</p>
//此代码本意是在页面显示括号中的数据,但却在显示中包括了<p>标签。
- 解决:
<p v-html="courseWebVo.description">{{courseWebVo.description}}</p>
2.代码错误
2.1 粗心点一
- 出错位置:vue-admin-template-master\src\views\edu\course\info.vue
- 错误效果:下图中课程分类第一个框应该显示文字类描述
- 错误代码:
this.subjectOneList = this.response.data.list
- 正确代码:
this.subjectOneList = response.data.list
2.2 粗心点二
export default{
getAllChapterVideo(courseId){
return request({
url: '/eduService/edu-chapter/getChapterVideo/'+courseId,
method: 'get',
})
},
对于以上导出方法的url,特别注意要首尾加/,缺一不可。
2.3 粗心点三
- 异常信息:
TypeError Cannot read property 'subjectLevelOne' of null
- 解决:从后端查询结果看出没有查询到,从而排查出id传入的值错误,再在前端中进行排查,发现是由于id值多加了一个1,导致其id错误,才在数据库中查不到结果。
2.4 粗心点四
- 跳转到创建的前端页面时,虽然地址栏显示了正确的页面地址,页面却显示
Network Error
,这样的错误一般可以排查前端的调用的方法的js文件(例如’@/api/xx.js’),看是否地址写错。
2.4 粗心点五(微信支付)
- 生成二维码和支付时的httpclient的url不同
1.支付时:
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
2.生成二维码时:
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
3.注意操作
3.1 每个小节的视频上传出现共享错误
- 异常说明:例如第一个小节视频上传成功,再添加第二个小节时再来一个视频上传会出现视频已上传,请删除再重新上传的情况,即使用了第一个小节的视频上传。
- 解决:每个小节视频上传成功并创建好这个小节后,记得刷新该页面。
3.2 nuxt前端页面的幻灯片等不能显示(实际是调用controller方法被拦截)
- 异常描述:
Access to XMLHttpRequest at http:XXX from origin http:XXX has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested reso
- 解决:出错是在项目中对nginx的地址配置上,如下
第一种:nuxt框架中的baseURL的最后几位数应该和nginx配置文件中的listen xxx的xxx一样。
第二种:项目前端框架中,同理也是注意BASE_API端口与nginx配置文件中要一致。
3.3 登录时报json错误
- 报错原因:解析的userStr是已经是对象,而parse是将字符串转成对象。
this.loginInfo = JSON.parse(userStr)
- 解决方法:如下图即是加了JSON.stringify()解决了问题,因为可以先将返回的数据通过JSON.stringify()转成字符串,再使用parse就不会报错。
//解决问题前
loginApi.getLoginUserInfo().then(response =>{
this.loginInfo = response.data.data.userInfo
cookie.set('guli_ucenter',this.loginInfo,{domain: 'localhost'})
window.location.href = "/";
})
//解决问题后
loginApi.getLoginUserInfo().then(response =>{
this.loginInfo = response.data.data.userInfo
cookie.set('guli_ucenter',JSON.stringify(this.loginInfo),{domain: 'localhost'})
window.location.href = "/";
})
3.4 页面误导报错
由上图以为是teacherName有问题,但实际排查处理是对象的gmtCreate和gmtModified属性没有添加自动生成的注解,导致出现null的情况。
四.不熟练记录
- 粗心点一处的如下代码:
course.getCourseInfoById(this.courseId)
.then(response => {
this.courseInfo = response.data.courseInfoVo
subject.getSubjectList()
.then(response => {
this.subjectOneList = response.data.list
for(var i=0;i<this.subjectOneList.length;i++){
var oneSubject = this.subjectOneList[i]
if(oneSubject.id == this.courseInfo.subjectParentId){
this.subjectTwoList = oneSubject.children
}
}
})
this.getListTeacher()
})
五.小bug
1.表单回显与清空
- 问题描述:第一次点击修改回显数据,第二次点击添加讲师会到与修改操作相同的表单页,但是会是会回显之前的数据,此时正确的情况应该是清空了数据的空表单项。
- 解决(详细说明在三.前端Vue的1.2路由切换):
#第一步判断路径是否有id,有则修改,没有则清空
methods:{
init(){
if(this.$route.params && this.$route.params.id){
const id =this.$route.params.id
this.getInfo(id)
}else{
this.teacher = {}
}
}
},
created(){
this.init()
},
watch:{
$route(to,from){
this.init()
}
}