⭐ 作者简介:码上言
⭐ 代表教程:Spring Boot + vue-element 开发个人博客项目实战教程
⭐专栏内容:零基础学Java、个人博客系统
👦 学习讨论群:530826149
项目部署视频
https://www.bilibili.com/video/BV1sg4y1A7Kv/?vd_source=dc7bf298d3c608d281c16239b3f5167b
文章目录
一、Bug修改和插件安装
经过前面的代码接口测试,基本的功能都可以实现了,但是还是有存在的小错误,感谢读者给我提出来的,现在在这里更改一下,用户表里的手机字段设置的是11位
,我们现在把那个11去掉,然后在User.java
中把手机号的Integer
类型改成String
类型就可以了。
SQL语句更改为:
`phone` BIGINT NOT NULL DEFAULT 0 COMMENT '手机号',
User.java
更改为:
/**
* 手机号
*/
private String phone;
接下来我们要安装一个关于Mybatis
的插件,这个插件主要是方便我们快速从代码跳转到mapper及从mapper返回代码。
和以前安装插件一样,在IDEA软件中打开左上角的File中找到Setting
,然后选择Plugins
进行搜索这个插件,安装完后重启IDEA即可。
安装完之后,再打开mapper包里面的类,多出来了一个绿色箭头。点击绿色箭头就能跳转到mapper.xml
中的具体实现的sql语句中。如下图所示:
二、调试
这一篇我们不往下继续写,来讲一下在我们开发中很重要的一个流程,那就是debug
调试程序,在我们写程序的时候难免会有很多的bug存在,有的是一眼就能看出来的报错,还有的是一些逻辑的问题或者是有异常等无法得到想要的结果,这时候靠我们去用眼看或者去一行一行读,这些也不一定能解决出问题,尤其是我们初学者,代码都看不懂读个毛线代码去找错误,这时候调试就突出了优越感,接下来我带大家一起来学习。
1、Debug启动项目
这个调试也要启动项目,但并不是我们平时起的按钮,启动debug
是用甲壳虫
起的,如下图所示,打开你的项目,在右上角有个甲壳虫样子的图标,点击这个就是debug启动。
点击这个小虫子按钮,等待项目启动。
项目启动起来之后,我们先测试一下添加的接口进行调试。
首先我们在接口的入口处打一个断点,也就是Controller
层的地方,断点打在增加的方法里。出现了红色打钩的就是打断点。
然后在Controller
调用的Service
的实现类层的增加方法中打一个断点。
然后,我们看下控制台的数据,看这正是我们要传过来的数据,目前id和创建时间都是空,因为我们没有传值,都是数据表中自动加载的字段。以后我们调试的时候都是要注意这些请求数据的走向以及变化。
按F8或者下图的小图标,再往下走一步跳到我们Service
的实现类中。
然后就跳到了这个类中,看着数据也过来了。
然后再往下走一步,神奇的事情发生了,id变成了2,说明数据可能插入成功了。
此时没有报错,再往下走一步,又跳到了Controller
层中,返回结果。
再走一步,就跳到了这里。
到这里说明走完了流程。我们去看下数据库有没有数据。
id为2的是刚刚添加成功的,debug流程走完了。
我们这里没有刻意去测试错误的程序,今天就先熟悉一下调试debug
的流程,以后还会再继续使用的,如何去发现错误等操作。
三、用户密码加密
我们现在的用户的密码都是明文存储的,这是非常不安全的,在正常的工作开发中,基本上公司都有自己的加密方式,我们这里都平常的学习或者登录自己的博客,没有什么商业价值类的东西,所以我们加密采用MD5加密
,对于我们自己的博客来说也足够了。
在我们添加加密类的时候,我们先引入一个工具,非常的好用,以后开发的时候可以经常用到。
官方文档:https://www.hutool.cn/docs/#/
在我们的项目pom.xml
依赖它的包。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.16</version>
</dependency>
首先我们在项目的util包
中新建一个 MD5Util.java
类,里面有一个MD5方法,参数是我们要传的密码,代码的逻辑大家有时间可以研究研究。最下面还有一个main
方法,可以自己测试一下,看看加密后的密码是多少。
package com.blog.personalblog.util;
import cn.hutool.core.util.StrUtil;
import java.security.MessageDigest;
/**
* @author: SuperMan
* 欢迎关注我的公众号:码上言
* @create: 2021-11-14
*/
public class MD5Util {
public static String MD5(String s) {
if (StrUtil.isEmpty(s) || StrUtil.isBlank(s)) {
return null;
}
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
try {
byte[] btInput = s.getBytes();
MessageDigest mdInst = MessageDigest.getInstance("MD5");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
public static void main(String[] args) {
String str = "123789";
System.out.println(MD5(str));
}
}
加密的方法有了,接下来我们要在我们项目中使用这个方法,我们将数据一进来就进行密码加密,所以在Controller
类进行判断和加密,在添加和修改的时候进行加密存储,我们页面不展示用户名的密码。
代码如下:
/**
* 添加用户
* @return
*/
@PostMapping("/create")
public JsonResult<Object> userCreate(@RequestBody @Valid User user) {
if (StrUtil.isEmpty(user.getPassWord())) {
return JsonResult.error("密码为空,请填写密码!");
}
//密码加密存储
user.setPassWord(MD5Util.MD5(user.getPassWord()));
userService.createUser(user);
return JsonResult.success();
}
/**
*
* 修改用户
* @return
*/
@PostMapping("/update")
public JsonResult<Object> userUpdate(@RequestBody @Valid User user) {
if (StrUtil.isEmpty(user.getPassWord())) {
return JsonResult.error("密码为空,请填写密码!");
}
//密码加密存储
user.setPassWord(MD5Util.MD5(user.getPassWord()));
userService.updateUser(user);
return JsonResult.success();
}
此时就是对密码进行存储加密,写到此时完我又想起前几天一个粉丝说手机号的问题,我们这里也在加一个手机号验证的工具吧,我们在Util包
中新建一个PhoneUtil.java
类
package com.blog.personalblog.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author: SuperMan
* 欢迎关注我的公众号:码上言
* @create: 2021-11-14
*/
public class PhoneUtil {
/**
* 验证手机号
* @param mobile
* @return
*/
public static boolean checkMobile(String mobile){
String phone_regex = "^((13[0-9])|(14[1,2,3,5,7,8,9])|(15[0-9])|(166)|(191)|(17[0,1,2,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
if (mobile.length() != 11) {
return false;
} else {
Pattern p = Pattern.compile(phone_regex);
Matcher m = p.matcher(mobile);
boolean isPhone = m.matches();
if (!isPhone) {
return false;
}
return true;
}
}
}
此时,我们再返回Controller
层,进行手机号的验证,可以看出我们的工具类的实现流程,如果是正常的手机号会返回一个true,如果是错误的手机号会返回false。
完整代码如下:
package com.blog.personalblog.controller;
import cn.hutool.core.util.StrUtil;
import com.blog.personalblog.util.JsonResult;
import com.blog.personalblog.entity.User;
import com.blog.personalblog.service.UserService;
import com.blog.personalblog.util.MD5Util;
import com.blog.personalblog.util.PhoneUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* @author: SuperMan
* 欢迎关注我的公众号:码上言
* @create: 2021-11-03
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
UserService userService;
/**
* 用户列表
* @return
*/
@PostMapping("/list")
public JsonResult<Object> list() {
List<User> userList = userService.findAll();
return JsonResult.success(userList);
}
/**
* 添加用户
* @return
*/
@PostMapping("/create")
public JsonResult<Object> userCreate(@RequestBody @Valid User user) {
if (StrUtil.isEmpty(user.getPassWord())) {
return JsonResult.error("密码为空,请填写密码!");
}
//密码加密存储
user.setPassWord(MD5Util.MD5(user.getPassWord()));
//判断手机号,这里用hutool工具类也可以
if (!PhoneUtil.checkMobile(user.getPhone())) {
return JsonResult.error("手机号码格式错误!");
}
userService.createUser(user);
return JsonResult.success();
}
/**
*
* 修改用户
* @return
*/
@PostMapping("/update")
public JsonResult<Object> userUpdate(@RequestBody @Valid User user) {
if (StrUtil.isEmpty(user.getPassWord())) {
return JsonResult.error("密码为空,请填写密码!");
}
//密码加密存储
user.setPassWord(MD5Util.MD5(user.getPassWord()));
//判断手机号,这里用hutool工具类也可以
if (!PhoneUtil.checkMobile(user.getPhone())) {
return JsonResult.error("手机号码格式错误!");
}
userService.updateUser(user);
return JsonResult.success();
}
/**
* 删除
* @return
*/
@PostMapping("/delete/{id}")
public JsonResult<Object> userDelete(@PathVariable(value = "id") int id) {
userService.deleteUser(id);
return JsonResult.success();
}
}
以上就是加了两个验证,大家可以先测试一下,手机号如果错误是否报错,添加的密码是否在数据库中加密。
写完后,我们启动项目,打开Postman
进行数据添加,首先验证密码是否加密存储。
然后再测试手机号错误是否给返回错误信息。我输了10位的手机号,请求接口就给了错误的返回信息,说明加的两个工具都是可以。
四、接入Swagger接口文档
这个Swagger
我以前写过这篇文章,这里为了教程的完整性,我将那边的内容再放到这里来说一下,结合我们的项目进行整合。
1、什么是Swagger?
做为一个后端开发人员或者是前端开发人员,总归是要沟通调试项目的,前端要接口数据,不知道接口地址,我总不能一个一个的把接口地址发给他吧,前端可能要打人了,后端觉得编写及维护接口文档会耗费不少精力,所以双方经常抱怨,经常扯皮,有这时间摸摸鱼不好嘛,所以Swagger就来接手这个重任,将项目的接口进行管理。所以前端只需要这一份接口文档就可以拿到数据,进行数据的处理等。提高开发效率。
1.1、Swagger介绍
官方网址:Swagger官网
1.2、使用Swagger的好处
● 无依赖
UI 适用于任何开发环境,无论是本地还是 Web。
● 人性化
允许最终开发人员轻松交互并尝试您的 API 公开的每一个操作,以便于使用。
● 易于导航
使用分类整齐的文档快速查找和使用资源和端点。
● 所有浏览器支持
通过适用于所有主要浏览器的 Swagger UI 迎合所有可能的场景。
● 完全可定制的
样式并通过完整的源代码访问以您想要的方式调整您的 Swagger UI。
● 完整的 OAS 支持
可视化 Swagger 2.0 或 OAS 3.0 中定义的 API。
2、项目中如何载入Swagger?
说到这,有人会问,该如何把Swagger
引用到项目中呢,不会是YY意想的吧,肯定不是,只需要导个包就可以了。有人又问:在哪导包,导什么包?
我来告诉你,就在项目的pom.xml
中,复制粘贴以下代码,就完成了Swagger加载到项目中了。
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
添加完,等待下载完包即可。此时Swagger已经加入了项目中。
3、如何使用Swagger?
准备工作结束啦,那如何使用呢?是啊,如何使用啊,有人说:接口文档肯定要在接口使用,我转身给你一个大大的赞,说的太对了,最主要的作用就是在接口上使用。接下来跟我来学习如何使用。
3.1、接口归类
首先我们在Controller类
上加入一个Swagger注解:@Api
主要是描述这个Controller是哪一个模块的接口,分类明确。假如是用户的接口类。那么这个类会有对用户的增删改查不同的方法。
@Api(tags = "用户管理") //每个Controller上加上一个@Api注解
@RestController
@RequestMapping("/user")
public class UserController {
}
3.2、接口方法
大的分类标注好了,下面则是每个接口方法的标题,我们在每个方法的上面添加一个@ApiOperation
注解,描述这个接口方法的功能,是删除还是修改或者添加等。
UserController.java
完整代码:
package com.blog.personalblog.controller;
import cn.hutool.core.util.StrUtil;
import com.blog.personalblog.util.JsonResult;
import com.blog.personalblog.entity.User;
import com.blog.personalblog.service.UserService;
import com.blog.personalblog.util.MD5Util;
import com.blog.personalblog.util.PhoneUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* @author: SuperMan
* 欢迎关注我的公众号:码上言
* @create: 2021-11-03
*/
@Api(tags = "用户管理")
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
UserService userService;
/**
* 用户列表
* @return
*/
@ApiOperation(value = "用户列表")
@PostMapping("/list")
public JsonResult<Object> list() {
List<User> userList = userService.findAll();
return JsonResult.success(userList);
}
/**
* 添加用户
* @return
*/
@ApiOperation(value = "添加用户")
@PostMapping("/create")
public JsonResult<Object> userCreate(@RequestBody @Valid User user) {
if (StrUtil.isEmpty(user.getPassWord())) {
return JsonResult.error("密码为空,请填写密码!");
}
//密码加密存储
user.setPassWord(MD5Util.MD5(user.getPassWord()));
//判断手机号,这里用hutool工具类也可以
if (!PhoneUtil.checkMobile(user.getPhone())) {
return JsonResult.error("手机号码格式错误!");
}
userService.createUser(user);
return JsonResult.success();
}
/**
*
* 修改用户
* @return
*/
@ApiOperation(value = "修改用户")
@PostMapping("/update")
public JsonResult<Object> userUpdate(@RequestBody @Valid User user) {
if (StrUtil.isEmpty(user.getPassWord())) {
return JsonResult.error("密码为空,请填写密码!");
}
//密码加密存储
user.setPassWord(MD5Util.MD5(user.getPassWord()));
//判断手机号,这里用hutool工具类也可以
if (!PhoneUtil.checkMobile(user.getPhone())) {
return JsonResult.error("手机号码格式错误!");
}
userService.updateUser(user);
return JsonResult.success();
}
/**
* 删除
* @return
*/
@ApiOperation(value = "删除用户")
@PostMapping("/delete/{id}")
public JsonResult<Object> userDelete(@PathVariable(value = "id") int id) {
userService.deleteUser(id);
return JsonResult.success();
}
}
到此,你以为就这样好了吗?没错,这就好了,此时我们启动项目,我们的项目是localhost:8081/blog
地址,然后加上Swagger的路径
。
点击http://localhost:8081/blog/swagger-ui/index.html则会出现以下界面。
看到了吧,有我刚才加的接口标签。此时Swagger添加好了,就可以正常的使用了。
4、配置Swagger
以上的步骤Swagger可以用了,但是为了项目的规范化,我们可以对这个页面进行改造,版本、指定controller包等操作。
我们在config配置包
中新建一个Swagger3Config.java
的配置类。
package com.blog.personalblog.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
* @author: SuperMan
* 欢迎关注我的公众号:码上言
* @create: 2021-11-15
*/
@Configuration
@EnableOpenApi
public class Swagger3Config {
@Bean
public Docket docket(){
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo()).enable(true)
.select()
//添加swagger接口提取范围,修改成指向你的controller包
.apis(RequestHandlerSelectors.basePackage("com.blog.personalblog.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("个人博客系统接口文档")
.description("个人博客系统")
.contact(new Contact("码上言", "https://xyhwh.gitee.io/blog/", "作者Email"))
.version("1.0")
.build();
}
}
这些没什么好说的,需要注意的是要指向你项目的controller包,下面的则是配置一些你接口文档的信息。
配置完,重启项目,还是访问原来的地址:http://localhost:8081/blog/swagger-ui/index.html
看,接口文档中出现了我们配置的信息,是不是感觉有点高大上的感觉,我们的项目也有了接口文档,前端直接拿这个接口文档就可以开发了,我们更新只需要重启下项目即可,但是这个文档在我们上线发布的时候要去掉,保证系统的信息安全。
好啦,以上就是我们所讲述的知识,这些虽然看着很零散,但都是项目刚开始最基础的东西,基本上都可以用得到,非常的方便。但对于我们本项目前后端都是我们自己搞就不太需要那么规范,但我们尽量按照开发规范来开发,养成好习惯。
上一篇:Spring Boot + vue-element 开发个人博客项目实战教程(九、Postman测试接口)
下一篇:Spring Boot + vue-element 开发个人博客项目实战教程(十一、文章分类功能实现)