在尝试做项目,说是课题也不像课题,老师给的权限很宽,那就按我的想法来尝试,记录一下尝试的过程和途中遇到的bug…
陈年旧项目简介
本来是打算在原项目的基础上做的,所以最开始选择了导入jar包然后添加到项目中。jar包的下载就是度娘。然后导入项目。
本项目用到了以下几个额外的jar包
POI: 读取excel数据
net.sf.json.JSONObject:转换beans,maps,collections, java arrays, xml等为JSON对象和反转换的java库
Gson是Google提供的用来在Java对象和JSON数据之间映射的JAVA类库
commons.fileupload.jar为web应用程序或者servlet提供文件上传功能。
IDEA项目导入jar包的方法有两个
- File –> Project Structure->Modules->Dependencies,点绿色的加号导入
- 需要导入的Jar包上,点击右键,选择Add as Library…
amap的使用方法
修改为maven项目
但是导jar包配置各种东西真的太麻烦了,于是决定用maven管理老项目,pom.xml配置真香。
打包成maven项目](https://blog.csdn.net/weixin_30348133/article/details/114560553)
- .classpath 文件:指定了源文件位置,con容器为JRE,编译输出位置。指定了java项目在逻辑结构与文件系统的物理结构之间的对应关系。
- 右键选择 JavaDemo(项目名称),选择“Configure –> Convert to Maven Project”, 填写“Group ID”和“Artifact Id”都为“JavaDemo”
- 完成pom.xml的修改—复制了一部分itheima的项目配置
- 参照标准的目录结构修修补补总算是弄好了
部署在tomcat上
报错:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat]....
搜索了好几个回答,发现相似点是jar包问题,就试着删除web目录下的lib目录,证实报错原因是jar包的重复,问题解决。原来的项目编码是gbk的,编译出错。为了方便改为UTF-8,可以使用批量处理脚本,完美解决
报错2:
Skipping non-war project
tomcat没有启动,无tomcat日志信息,解决方法:1
2
3
4<groupId>com.itheima</groupId>
<artifactId>maven_web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <!--加这一句-->到这里为止,终于部署到tomcat成功,但是页面乱码了,不要紧,肯定是编码问题。
报错3:Servlet不能正常访问,论版本兼容的重要性。tomcat各版本的兼容,其实是在运行其他项目时遇到的问题,一并归纳。
数据库设计
编码问题解决好了,那就进入数据库的连接。原本的数据库与前端页面的交互代码写得比较繁杂,这里可以优化为采用数据库连接池和Spring框架提供的JDBCTemplate来进行优化。
数据库的设计方面,数值范围是一个讨论问题。
- 报错:运行tomcat时无法连接到数据库,本地测试和连接其他的项目都可以,唯独这个项目不可以。尝试了给数据库更高的权限,尝试了改密码,都没有解决。啊卡了好久,解决无果。
- 本地测试了jdbc工具类和连接池工具类都没有问题。
- 优化注解注入,简化web.xml的配置
目前的计划:
- 了解已知代码的逻辑实现和已有的功能。
- 文献查询,聚类分析的基本方式和基于LoRa的应用
- 取合适的模型进行坐标点的分类
修改项目框架为Springboot
更新为主流的应用框架。参考了开源项目-mall
数据库连接
- 一边学一边做,首先使用之前新建的数据库,采用新学Mybatis框架
- 编写实体类 domain.User/domain.Data
- 编写dao接口 UserMapper/DataMapper
- 测试
导入静态资源和页面
静态资源放在static.asserts下面,页面放置在templates下
无法加载样式—莫名其妙又可以加载了
代替jsp使用Thymeleaf ,不是前后端分离的。
用json和ajax实现前后端分离—-原项目就是采用了前后端分离的做法,所以正好保留
原项目实现登录功能(伪):
使用SpringMVC的话就直接砍掉了servlet,使用Contoller替换掉servlet,SpringMVC嵌入了自动的json转换,只需要加一个@ResponseBody
反正折腾了半天是可以实现登录成功了,但是跳转了wmap.html页面。
添加了lombok
Lombok表达式—面向函数编程
MybatisGenerator
使用Mybatis Generator可以快速根据数据库中已经建立好的表来创建mybatis代码
发生错误,
The specified target project directory mall-tiny-01\src\main\resources does not exist
路径不对,参考博客解决,查看edit configuration拼接路径生成的文件到了另一模块上,果然还是路径错了
未报错但是没有产生文件,参考博客修改路径中的\为/,成功生成文件
报错
Column id, specified as an identity column in does not exist in the table.
参考博客解决,在生成器的配置文件里的数据库连接地址中添加:nullCatalogMeansCurrent=true
路径追加问题 参考博客
使用@MapperScan注解扫描多个包,参考
启动项目异常,
Result Maps collection already contains value for
,原因是Mybatis gennerator生成xml,但是如果同名xml之前已经存在,那么生成的时候会在xml里面在之前的代码后面继续追加,而不会覆盖同名的语句。因此有可能报这个错误。如果是再次生成代码,必须先将已经生成的代码删除,仔细检查一下xml文件看是否存在两个id为BaseResultMap的resultMap,删除多余的,只保留一个就可以解决问题。参考博客
Swagger-UI
使用步骤
- 添加项目依赖
- 添加Swagger2Config配置类
- 给Controller加注解
- 启动项目,线上观看结果 http://localhost:8080/swagger-ui.html。
报错:
Plugin 'org.springframework.boot:spring-boot-maven-plugin:' not found
解释最清楚的博客,解决方法是添加版本号
spring-boot-maven-plugin没有设置version,它会先去远程仓库找最新的版本,然后download到本地,然后完成maven操作等。但是远程仓库里没有相应的jar包,导致执行maven编译出错。因为远程仓库里已经有了最新版本的路径,它就不会使用已经存在的版本。
CommentGenerator自定义注释生成中,
org.mybatis.generator.api.dom.java.CompilationUnit;
中方法解析失败,Cannot resolve method 'isJavaInterface' in 'CompilationUnit'
果真是版本问题,Mybatis generator的版本由1.4.0改为1.3.7就好了。本菜鸡一个个试出来的,不知道有没有更好的方法。项目启动出错,
Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
据说是版本号的冲突,心累,未解决,把Swagger-UI和MybatisGenerator都删了,然后回到开始实现登录功能哈哈哈哈我又回来了,Springboot版本号改成了2.1.3.RELEASE,原来用的2.6.1,感谢博主的提供的思路。
The server time zone value '???ú±ê×??±??' is unrecognized or represents more than one time zone.
数据库和系统时区差异所造成的,解决方法加serverTimezone=GMT%2B8
,参考博客总之成功了^w^
修改Mybatis Generator注释生成规则—-待解决
CommentGenerator为MyBatis Generator的自定义注释生成器,修改addFieldComment方法使其生成Swagger的@ApiModelProperty注解来取代原来的方法注释,添加addJavaFileComment方法,使其能在import中导入@ApiModelProperty,否则需要手动导入该类,在需要生成大量实体类时,是一件非常麻烦的事。
Spring Security登录认证
学习了新项目有了新的想法,使用SpringSecurity实现登录功能。
Springboot使用pagehelper
pagehelper的使用方法有两种,集成成功。
- 错误:SpringBoot单元测试使用@Test没有run方法的问题 参考 因为改成了2.1.7.RELEASE,版本不同,项目的结构也不同。测试方法的public没了。然后改回了2.6.0.版本,但是仍然有问题。pagehelper循环依赖的问题。项目启动不了,我版本又改回了2.5.6,会标红但是可以运行。
- 引发了新问题,需要登陆才能查看swagger文档,但是登录密码错误,待解决,好像知道原因了,是因为添加了security和token,虽然还没有集成完全。
分析
继续完成security—-需要更改数据库
因为需要自定义
- UserDetailsService:SpringSecurity定义的核心接口,用于根据用户名获取用户信息,需要自行实现;
- UserDetails:SpringSecurity定义用于封装用户信息的类(主要是用户信息和权限),需要自行实现;
- 设计数据库—用MybatisGenerator生成model和mapper—完成service—controller
Hibernate-validator校验框架(待添加)
实现
错误:
Could not resolve placeholder 'jwt.secret' in value "${jwt.secret}"
忘记配置了获取权限列表,因为我的项目是简化版本的权限只需要,mall项目是四表联查找到权限封装为Permission对象,Security究竟是如何读取权限的呢
1
2
3
4
5
6
7
8
9public final class SimpleGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = 510L;
private final String role;
public SimpleGrantedAuthority(String role) {
Assert.hasText(role, "A granted authority textual representation is required");
this.role = role;
}
}使用Swagger测试接口时一直没反应,后来发现是Swagger配置类没有增加登录认证功能
错误:
Encoded password does not look like BCrypt
密码的加密方式不对,找到原因了,数据库取出的代码是未加密的,而mall的项目中数据库存的密码是加过密的,偷个懒先把他的密码拷贝过来试试。茅塞顿开,救命我会用debug了,找寻一个项目的运行逻辑可以打断点一步步运行。(迟来的领悟,其实之前看视频看到过)
错误:
java.lang.String is in module java.base of loader 'bootstrap'; com.tsuki.cartocar.mbg.model.UserInfo is in unnamed module of loader 'app'
类型转换错误1
2
3
4
5
6//AdminUserDetails,仍旧是权限定义错误
public Collection<? extends GrantedAuthority> getAuthorities() {
//返回当前用户的权限
return null;
}参考了博客
List<? extends Number> 定义了泛型的
上界
是 Number, 即 List 中包含的元素类型是 Number 及其子类. 而 List<? super Number> 定义了泛型的下界
, 即 List 中包含的是 Number 及其父类.permissionlist.stream() Stream API的聚合使用
获取权限的修改主要在三个文件,UserServiceImpl.java & SecurityConfig.java & AdminUserDetails.java & UserController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39//UserController
"获取用户所有权限(包括+-权限)") (
"/permission/{userId}", method = RequestMethod.GET) (value =
public CommonResult<List<UserInfo>> getPermissionList( String userId) {
UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);
List<UserInfo> permissionList = userService.getPermissionList(userInfo);
return CommonResult.success(permissionList);
}
//UserServiceImpl
public List<UserInfo> getPermissionList(UserInfo userInfo) {
List<UserInfo> permission = new ArrayList();
//String roleId = userInfo.getRoleId();
permission.add(userInfo);
return permission;
}
//SecurityConfig
public UserDetailsService userDetailsService() {
//获取登录用户信息
return username -> {
UserInfo userInfo = userService.getUserByUsername(username);
if (userInfo != null) {
List<UserInfo> permissionList = userService.getPermissionList(userInfo);
return new AdminUserDetails(userInfo,permissionList);
}
throw new UsernameNotFoundException("用户名或密码错误");
};
}
//AdminUserDetails
public Collection<? extends GrantedAuthority> getAuthorities() {
//返回当前用户的权限
return permissionList.stream()
.filter(permission -> permission.getRoleId()!=null)
.map(permission ->new SimpleGrantedAuthority(userInfo.getRoleId()))
.collect(Collectors.toList());
}
错误:
org.springframework.web.bind.MissingPathVariableException: Required URI template variable 'userId' for method parameter type String is not present
主要是自己对注解的理解不清楚导致的,@PathVariable请求路径名称写错了。错误:
java.sql.SQLException: Field 'id' doesn't have a default value
是因为MybatisGenerator生成的Mapper.xml中插入默认主键是自增的从而不插入主键,而我的不是。暂时的解决方式是修改主键为自增,参考博客也并没有解决。主键自增要求键值为int类型。都要改。。所以修改mapper中的insert方法,添加插入主键,成功!1
2
3
4
5
6
7
8
9<insert id="insert" parameterType="com.tsuki.cartocar.mbg.model.UserInfo">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.String">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user_info (id, username, password, role_id,
devID)
values (#{id, jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{roleId,jdbcType=VARCHAR},
#{devid,jdbcType=VARCHAR})
</insert>