提前声明,我也是刚做好这么个小模块,我就按照我的印象中的顺序重新又整了理了一遍,也方便我日后再回顾。可能会有一些问题,如果有哪些步骤问题请及时指正,谢谢
能做到的功能:
1阶:输入账号和密码,输入正确即可返回登录成功的信息,反之则登录失败
3阶:前端页面的注册也可以使用,注册完的帐号能直接登录
1.新建一个数据库
mysql安装配置教程,做到第6步就可以了http://t.csdnimg.cn/aQNQUnavicat安装和激活http://t.csdnimg.cn/ZDhYe打开navicat,在localhost里新建一个user库
在里面添加一个login表,添加如下字段,写一行如图的数据
(如果上一行的步骤不会,那就从建好user库的步骤之后开始,新建一个查询,输入如下代码)
CREATE TABLE `login` (
`id` int NOT NULL,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of login
-- ----------------------------
INSERT INTO `login` VALUES (1, 'admin', '123456');
SET FOREIGN_KEY_CHECKS = 1;
2.新建项目
jdk1.8以及idea安装配置http://t.csdnimg.cn/bQlMJ打开idea,新建一个Spring Boot 的 login项目
如果下一步有弹出这个相关说明的框,就在倒数第二行换一个Java的版本
如果都没有适合的,就在第一行的server URL改成aliyun/spring的url,再找找有没有合适的java版本
aliyun: https://start.aliyun.com
spring: https://start.spring.io
3.添加依赖
添加如下依赖,可以通过搜索查找
查看pom.xml文件再把其他依赖手动添加进去
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.38.0</version>
</dependency>
<!-- Druid 数据连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- jackson依赖包-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!--第一种方式导入校验依赖-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!--第二种方式导入校验依赖-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
4.新建资源包
右键main包,新建Directory包,在命名框下面有个现成的resource包,直接选中就能新建了
在resource包里新建file,命名为application.yml,如果图标变成一个小叶子,那就新建成功,在这里输入我们第一步建好的数据库的位置,代码在图片下面
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///user
username: root
password: root
上述 jdbc:mysql:///user = jdbc:mysql://localhost/user 就是本地的数据库的意思
5.建4个层
在example包下新建5个包,request是传入的实体包(dto),vo是返回的实体包,controller是控制层,service是逻辑层,mapper层则会连接数据库,在其对应的xml后缀文件写sql语句,查询数据库
1.在request和vo包下建实体类
新建UserRequest和UserVo类,在这里写与数据库对应的实体。
在这个包的上面写一个@Data注解,这样就可以不用写getter,setter之类的了
private Integer id;
private String name;
private String password;
2.添加util包下的类
MD5Util
// 加密方法:接收一个字符串明文,返回使用 MD5 加密后的哈希值
public static String encrypt(String plaintext) throws NoSuchAlgorithmException {
// 使用 MD5 算法创建 MessageDigest 对象
MessageDigest md = MessageDigest.getInstance("MD5");
// 更新 MessageDigest 对象中的字节数据
md.update(plaintext.getBytes());
// 对更新后的数据计算哈希值,存储在 byte 数组中
byte[] digest = md.digest();
// 将 byte 数组转换为十六进制字符串
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
// 返回十六进制字符串
return sb.toString();
}
// 解密方法:接收一个字符串明文和一个使用 MD5 加密后的哈希值,返回解密结果(true 表示匹配,false 表示不匹配)
public static boolean decrypt(String plaintext, String encrypted) throws NoSuchAlgorithmException {
// 调用加密方法计算出明文的哈希值
String decrypted = encrypt(plaintext);
// 比较计算得到的哈希值和输入的哈希值是否相同
return decrypted.equals(encrypted);
}
QccResponseStatus
public enum QccResponseStatus {
// 成功
SUCCESS(200, "操作成功"),
// 参数错误
BAD_REQUEST(400, "请求参数错误"),
// 未授权
UNAUTHORIZED(401, "未授权"),
// 禁止访问
FORBIDDEN(403, "禁止访问"),
// 资源未找到
NOT_FOUND(404, "资源未找到"),
// 内部服务器错误
INTERNAL_SERVER_ERROR(500, "内部服务器错误"),
// 其他错误
OTHER_ERROR(500, "其他错误");
private final int code;
private final String message;
QccResponseStatus(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
Result
@Data
public class Result<T> {
private int code;
private String message;
private T data;
public static Result<Void> ok (String massage) {
Result<Void> result = new Result<>();
result.code = QccResponseStatus.SUCCESS.getCode();
result.message = massage;
return result;
}
public static <T> Result<T> ok (T data, String message) {
Result<T> result = new Result<>();
result.code = QccResponseStatus.SUCCESS.getCode();
result.message = message;
result.data = data;
return result;
}
public static Result<Void> error (int code,String message) {
Result<Void> result = new Result<>();
result.code = code;
result.message = message;
return result;
}
}
StrUtils(暂时用不上,可以不写这个)
public class StrUtils {
private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+";
/**
* 生成指定长度的复杂随机字符串
*
* @param length 随机字符串长度
* @return 随机字符串
*/
public static String getComplexRandomString(int length) {
if (length < 1) {
throw new IllegalArgumentException("随机字符串长度必须大于等于1");
}
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int index = random.nextInt(CHARACTERS.length());
sb.append(CHARACTERS.charAt(index));
}
return sb.toString();
}
}
3.在controller包下建控制类
新建一个类,命名UserController。建好后在类的上面写一个注解@RestController
建议在这里也顺便把service包和mapper包里的类都提前写好,建不明白的话也可以先不建,继续跟着做吧。
我们先写登录功能,在UserController里添加如下代码
@Autowired
private UserService userService;
/**
* 用户登录
* @param userRequest
* @param result
* @return
*/
@PostMapping("doLogin")
public Result doLogin(@RequestBody @Valid UserRequest userRequest, BindingResult result) {
String password = userRequest.getPassword();
UserVo userVo = userService.isCorrect(userRequest);
if (userVo != null) {
userVo.setPassword(password);
return Result.ok(userVo,"success");
}
else {
return Result.error(500,"账号或密码错误");
}
}
字面讲解
我们会使用post请求来登录,请求中还带有账号和密码,controller接收到请求后会将这些值传给service,然后会返回一个对象。
如果返回的这个对象有数据,那么就表明账号密码正确,登录成功,返回成功的信息
如果对象是null,那么就表明没有在数据库表里查到对应信息,账号密码错误,返回失败的信息
哪些代码是爆红的,就用快捷键Alt+Enter引入一下,如果UserService没有引入,先往下看步骤三的第一段,把UserService建好再回来引入。
现在不能引入的应该是isCorrect,因为它需要在service层里继续写东西
4.在service包下建逻辑层
这次建的不是类了,而是接口interface。建好之后鼠标放在UserService上,快捷键Alt+Enter一下,选择Implement interface,然后再在路径后面添加 .impl,继承的包就在这个包下了,基础工作完成。建好后在UserServiceImpl类的上面写一个注解@Service
在UserController里快捷键Alt+Enter一下,在UserService里创建接口
这时我们来到UserServiceImpl类里,会看到标题划一条红波浪线,在线上快捷键Alt+Enter把方法带过来
在UserServiceImpl里添加如下代码
@Autowired
private UserMapper userMapper;
/**
* 用户登录
* @param userRequest
* @return
*/
@Override
public UserVo isCorrect(UserRequest userRequest) {
try {
userRequest.setPassword(MD5Util.encrypt(userRequest.getPassword()));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
return userMapper.select(userRequest);
}
当前暂时还不需要对传过来的值进行修改,所以现在会相对简单一些,接下来就是UserMapper了
5.在mapper包下建逻辑层
你可以用之前的方法在mapper手动建一个接口mapper
也可以在UserServiceImpl里Alt+Enter自动创建UserMapper,不过记得改一下创建路径
建好后在UserMapper接口上面写一个注解@Mapper
把UserServiceImpl的select方法快捷键(Alt+Enter)到mapper上
对比一下下面这行代码,把自动建好的方法补充补充。
UserVo select(@Param("user") UserRequest userRequest);
在resource包下逐级新建com example mapper包,路径与上面的mapper是可以对应上的
先不着急建xml文件,我们回到之前的mapper里,快捷建标题,选择如图的选项,然后选择我们刚才建好的路径地址,xml文件就自动生成了
回到mapper,在select方法上加快捷键,选择第一个生成报表,就会在xml文件里生成一个标签,这里就是用来写sql增删改查语句的。
我们要在后端查数据库判断是否账密是对的,所以用查询语句,在xml新生成的标签里写↓
<select id="select" resultType="com.example.vo.UserVo">
SELECT * FROM login
<where>
name = #{user.name}
<if test="user.password!=null and user.password!=''">
and password = #{user.password}
</if>
</where>
</select>
如此一来,框架基本搭好了,已经能完成开头1阶的功能了,运行主类(java.com.example.LoginApplication)试试看吧
Q:怎么查
A:用postman查,下好之后按照下图的步骤一步一步做,点击发送看看结果吧
第五步
{
"name":"admin",
"password":"123456"
}
下一步请转战