将application.properties重命名为application.yml,并另外创建application-dev.yml。
在application.yml中添加配置:
- # 激活Profile配置
-
- # 指定Mybatis的XML文件的位置
-
- # 响应JSON时不包含为null的属性
-
- # 开启Knife4j的增强模式
在application-dev.yml中添加配置:
- # 指定服务端口
-
- # 配置连接数据库的参数
-
- # 日志显示级别
在根包下创建config.MybatisConfiguration配置类,在此配置类上添加@MapperScan以配置接口所在的包(此包尚且不存在,可以此时就把包也创建出来)。
在根包下创建config.Knife4jConfiguration配置类,注意,此类中需要调整控制器类所在的包(此包尚且不存在,可以此时就把包也创建出来)。
在根包下创建config.WebMvcConfiguration配置类,实现WebMvcConfigurer接口,重写addCorsMappings()方法,以解决跨域访问的问题(此问题尚未出现,但可提前完成此项配置)。
完成以上配置后,应该在src/test/java下找到默认的配置类,执行其中的contextLoads()方法,此方法的方法体是空的,理应通过测试!
继续在测试类中添加方法,尝试连接数据库,以检查以上配置的“连接数据库的参数”是否正确:
- @Autowired
- DataSource dataSource; // 导包时注意:此接口是javax.sql包中的
-
- @Test
- void testConnection() throws Throwable {
- dataSource.getConnection();
- }
接下来,将此前项目中的“Mybatis拦截器(用于解决gmt_create、gmt_modified的)”复制到当前项目中,并在MybatisConfiguration中添加配置。
完成后,再次执行以上测试,确保新增代码后仍能够正常通过测试。
创建pojo.entity.Admin类,类的属性与ams_admin表保持一致。
在根包下创建mapper.AdminMapper接口,并在接口中添加抽象方法:
int insert(Admin admin);
为了保证后续登录时使用的“用户名”是唯一的,在插入数据之前,还需要检查“此用户名是否已经存在”,则需要实现查询功能:
int countByUsername(String username);
在src/main/resources/mapper下,通过粘贴得到AdminMapper.xml,在此文件中配置以上2个抽象方法映射的SQL语句:
-
- <mapper namespace="AdminMapper接口的全限定名">
- <insert id="insert" useGeneratedKey="true" keyProperty="id">
- 插入管理员数据的SQL语句,不需要处理gmt_create和gmt_modified
- insert>
-
- <select id="countByUsername" resultType="int">
- 根据用户名统计数量的SQL语句
- select>
- mapper>
在src/test/java下的根包下,创建mapper.AdminMapperTests测试类,在此类中自动装配AdminMapper对象,并测试以上2个方法:
- package cn.tedu.csmall.passport.mapper;
-
- import cn.tedu.csmall.passport.pojo.entity.Admin;
- import lombok.extern.slf4j.Slf4j;
- import org.junit.jupiter.api.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
-
- @SpringBootTest
- @Slf4j
- public class AdminMapperTests {
-
- @Autowired
- AdminMapper mapper;
-
- @Test
- void testInsert() {
- Admin admin = new Admin();
- admin.setUsername("test-admin-001");
- admin.setPassword("123456");
-
- log.debug("插入数据之前,参数={}", admin);
- int rows = mapper.insert(admin);
- log.debug("插入数据完成,受影响的行数={}", rows);
- log.debug("插入数据之后,参数={}", admin);
- }
-
- @Test
- void testCountByUsername() {
- String username = "test-admin-007";
- int count = mapper.countByUsername(username);
- log.debug("根据用户名【{}】统计,数量={}", username, count);
- }
-
- }
关于业务接口
在根包下创建pojo.dto.AdminAddNewDTO类,在此类中添加”添加管理员时需要提交的请求参数“,包括:username、password、nickname, avatar, phone, email, description, enable。
在根包下创建service.IAdminService接口,并在此接口中添加”添加管理员“的抽象方法:
- public interface IAdminService {
- void addNew(AdminAddNewDTO adminAddNewDTO);
- }
关于业务实现类
在根包下创建web.ServiceCode接口,此接口可参考此前项目中的同名接口。
在根包下创建ex.ServiceException,此异常类可参考此前项目中的同名异常类。
在根包下创建service.impl.AdminServiceImpl类,实现以上IAdminService接口,添加@Service注解,并在类中自动装配AdminMapper对象。
关于重写的方法:
- @Override
- public void addNew(AdminAddNewDTO adminAddNewDTO) {
- // 日志
- // 从参数中获取尝试添加的管理员的用户名
- // 调用adminMapper对象的countByUsername()方法进行统计
- // 判断统计结果是否大于0
- // 是:日志,抛出ServiceException
-
- // 创建新的Admin对象
- // 调用BeanUtils.copyProperties()方法将参数的属性值复制到以上Admin对象中
- // 补全Admin对象的属性值:loginCount >>> 0
- // 日志
- // 调用adminMapper对象的insert()方法插入数据,并获取返回的受影响的行数
- // 判断受影响的行数是否不等于1
- // 是:日志,抛出ServiceException
- }
编写并执行测试
在src/test/java下的根包下,创建service.AdminServiceTests测试,在此类中测试以上方法:
- package cn.tedu.csmall.passport.service;
-
- import cn.tedu.csmall.passport.ex.ServiceException;
- import cn.tedu.csmall.passport.pojo.dto.AdminAddNewDTO;
- import lombok.extern.slf4j.Slf4j;
- import org.junit.jupiter.api.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
-
- @Slf4j
- @SpringBootTest
- public class AdminServiceTests {
-
- @Autowired
- IAdminService service;
-
- @Test
- void testAddNew() {
- AdminAddNewDTO adminAddNewDTO = new AdminAddNewDTO();
- adminAddNewDTO.setUsername("test-admin-005");
- adminAddNewDTO.setPassword("12345678");
-
- try {
- service.addNew(adminAddNewDTO);
- log.debug("添加管理员成功!");
- } catch (ServiceException e) {
- log.debug(e.getMessage());
- }
- }
-
- }
在根包下创建web.JsonResult类,可参考此前项目中的同名类。
在根包下创建controller.AdminController类,在类上添加@RequestMapping("/admins")和@RestController注解,并在类中自动装配IAdminService对象。
在类中添加处理请求的方法:
- @PostMapping("/add-new")
- public JsonResult
addNew(AdminAddNewDTO adminAddNewDTO) { - // 日志
- // 调用Service对象实现添加
- // 返回
- }
完成后,启动项目,可通过Knife4j的调试功能测试添加管理员,当添加成功时,将响应{ "state": 20000 },当添加失败时(用户名已被占用),会出现500错误。
在根包下创建ex.handler.GlobalExceptionHandler,可参考此前项目中的同名类。
完成后,再次启动项目,再次通过Knife4j的调试功能测试添加管理员,当添加失败时(用户名已被占用),将响应{ "state": 40900, "message": "xxxx" }。
接下来,还可以在AdminController、AdminAddNewDTO中添加相关注解,使得Knife4j文档更加易于阅读。
另外,还可以基于Spring Validation对请求参数进行检查。
先创建AdminAddNewView.vue视图,并在router/index.js中添加配置,其路径应该是/sys-admin/temp/admin/add-new,完成后,通过 `http://localhost:8888/sys-admin/temp/admin/add-new`可以访问到此页面。
在HomeView的菜单中,添加对应的菜单项,以确定点击菜单项可以打开此页面。
将BrandAddNewView中的代码全部复制到AdminAddNewView中,先调整输入框的数量,并修改显示在网页中的文字信息,例如标题、输入框的提示等,然后调整各输入框的设计中的属性名,并同步修改JavaScript中ruleForm的属性,然后,按需设计验证规则。
最后,调整使用axios发请求的部分代码,需要修改url的值,和输出、日志等位置的文本。
存储到数据库中的密码,必须经过加密处理!
用户提交的原始密码通常称之为原文、明文,加密后的数据通常称之为密文。
对于需要存储到数据库中的密码,不可以使用加密算法!
提示:加密算法是用于保障传输过程安全的,并不是用于保障存储的数据的安全的!
通常,会使用消息摘要算法对密码进行加密处理!
消息摘要算法典型的特征是:
典型的消息摘要算法是:
MD系列算法都是128位算法,即其运算结果是128个二进制位。
SHA-1是160位算法(已被破解),SHA-256是256算法,SHA-384是384位算法,SHA-512是512位算法。
关于处理密码加密,应该:
- package cn.tedu.csmall.passport;
-
- import lombok.extern.slf4j.Slf4j;
- import org.junit.jupiter.api.Test;
- import org.springframework.util.DigestUtils;
-
- import java.util.UUID;
-
- @Slf4j
- public class Md5Tests {
-
- @Test
- public void testMd5() {
- for (int i = 0; i < 10; i++) {
- String rawPassword = "123456";
- String salt = UUID.randomUUID().toString();
- String encodedPassword = DigestUtils.md5DigestAsHex(
- (salt + rawPassword + salt + rawPassword + salt).getBytes());
- // 123456abvckj,fsd789u4rkjldsiu
- log.debug("原文={}, 密文={}", rawPassword, encodedPassword + salt.replaceAll("-", ""));
- // 原文=123456, 密文=e10adc3949ba59abbe56e057f20f883e
- // 0 >> xx
- // 1 >> xx
- }
- }
-
- }