实战篇02:注册接口
一、注册
1.1、接口信息
1.1.1 基本信息
请求路径:/user/register
请求方式:POST
接口描述:该接口用于注册新用户
1.1.2 请求参数
请求参数格式:x-www-form-urlencoded
请求参数说明:
参数名称 | 说明 | 类型 | 是否必须 | 备注 |
---|---|---|---|---|
username | 用户名 | string | 是 | 5~16位非空字符 |
password | 密码 | string | 是 | 5~16位非空字符 |
请求数据样例:
username=zhangsan&password=123456
1.1.3 响应数据
响应数据类型:application/json
响应参数说明:
名称 | 类型 | 是否必须 | 默认值 | 备注 | 其他信息 |
---|---|---|---|---|---|
code | number | 必须 | 响应码, 0-成功,1-失败 | ||
message | string | 非必须 | 提示信息 | ||
data | object | 非必须 | 返回的数据 |
响应数据样例:
{
"code": 0,
"message": "操作成功",
"data": null
}
1.2、生成结果实体类
- 在pojo文件夹中新建Result.java
package com.example.bigevent.pojo;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@NoArgsConstructor // 使用lombok生成无参数构造方法
@AllArgsConstructor // 使用lombok生成全参数构造方法
@Data
public class Result<T> {
private Integer code;//业务状态码 0-成功 1-失败
private String message;//提示信息
private T data;//响应数据
//快速返回操作成功响应结果(带响应数据)
public static <E> Result<E> success(E data) {
return new Result<>(0, "操作成功", data);
}
//快速返回操作成功响应结果
public static Result success() {
return new Result(0, "操作成功", null);
}
public static Result error(String message) {
return new Result(1, message, null);
}
}
1.3、业务分析
- 在Controller文件夹中新建一个UserController用于实现注册
- 声明PostMapping,url路径:register
- 方法:确认用户名是否被占用;进行注册
- 在Service文件夹中生成UserService
- 在Mapper中生成UserMapper,用于和数据库进行交互
1.4、编写UserController
- 由于需要查询数据库,所以需要使用service层,因此自动化注入一个userService,待会实现它
- 定义一个注册行为,接收用户名和密码,检查用户名是否被占用,通过则进行注册
package com.example.bigevent.controller;
import com.example.bigevent.pojo.Result;
import com.example.bigevent.pojo.User;
import com.example.bigevent.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public Result register(String username, String password){
// 查询用户名是否被占用
User u = userService.findByUserName(username);
if (u==null){
// 没有占用,进行注册
userService.register(username,password);
return Result.success();
}else {
return Result.error("用户名已被占用");
}
// 注册
}
}
1.5、编写UserService
- 编写接口,定义查询用户名函数和注册函数
package com.example.bigevent.service;
import com.example.bigevent.pojo.User;
public interface UserService {
// 根据用户名查询用户
User findByUserName(String username);
// 注册
void register(String username, String password);
}
- 编写实体类
- 定义数据库交互mapper
- 在注册中,对密码进行md5加密
- 在pom中引入md5加密工具依赖
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
package com.example.bigevent.service.impl;
import com.example.bigevent.mapper.UserMapper;
import com.example.bigevent.pojo.User;
import com.example.bigevent.service.UserService;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User findByUserName(String username) {
return userMapper.findByUserName(username);
}
@Override
public void register(String username, String password) {
// 密码md5加密
String md5String = DigestUtils.md5Hex(password);
userMapper.add(username,md5String);
}
}
1.6、添加UserMapper
- 编写接口,定义用户查找和添加功能
package com.example.bigevent.mapper;
import com.example.bigevent.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
// 根据用户名进行查询
@Select("select * from user where username=#{username}")
User findByUserName(String username);
// 添加
@Insert("insert into user (username,password,create_time,update_time) " +
"values (#{username},#{md5String},now(),now())")
void add(String username, String md5String);
}
1.7、功能测试
- 启动springboot工程
- 使用postman发送post信息,进行注册
1.8、Controller层增加参数校验
- 添加依赖,使用Spring Validation,对注册接口的参数进行合法性校验
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.2.1</version>
</dependency>
- 在参数前面添加@Pattern注解,使用户名和密码符合5~16位非空字符校验规则
- 在Controller类上添加@Validated注解
package com.example.bigevent.controller;
import com.example.bigevent.pojo.Result;
import com.example.bigevent.pojo.User;
import com.example.bigevent.service.UserService;
import jakarta.validation.constraints.Pattern;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
@Validated
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password){
// 查询用户名是否被占用
User u = userService.findByUserName(username);
if (u==null){
// 没有占用,进行注册
userService.register(username,password);
return Result.success();
}else {
return Result.error("用户名已被占用");
}
// 注册
}
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
1.9、参数校验失败处理:使用全局异常处理器
- 创建异常文件夹exception
- 在包exception中创建异常处理器:GlobalExceptionHandler
- 在类名上添加异常注解:@RestControllerAdvice
- 将异常返回到前端
package com.example.bigevent.exception;
import com.example.bigevent.pojo.Result;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Result handleException(Exception e){
e.printStackTrace();
return Result.error(StringUtils.hasLength(e.getMessage())? e.getMessage():"操作失败");
}
}