<从零学习javaWeb> 3. 前后端开发登录接口

前置

完成<从零学习javaWeb> 2. 数据表设计和三层架构的操作后,根据接口文档实现一些简单的Controller层接口,并用IDEA进行测试。

1. 登录逻辑

1.1 接口文档

  • 接收参数:用户账号、密码
  • 请求类型:POST
  • 请求体:JSON格式
  • 返回值:用户信息(脱敏)

1.2 逻辑

  1. 账号密码是否合法

    • 非空
    • 长度
    • 特殊字符
  2. 密码是否正确

  3. 用户信息脱敏

  4. 记录登录态(seesion),调HttpServletRequest的接口

    java 复制代码
    //记录session
    request.getSession().setAttribute(USER_LOG_STATE, newUser);

1.3 Controller层实现

1.3.1 实现的方法

  • 注册(上期在Service层实现)
  • 登录

1.3.2 知识点

  • 多个参数的请求可以单独封装成一个请求实体类,如注册接收三个字符串,将这三个字符串封装到UserRegisterRequest中
  • 用@Date自动生成一个实体类的get和set等
  • @RestController修饰Controller层的类,方便其接收和响应http请求,其包括@Controller,修饰类并创建bean;还有@ResponseBody,表示返回值都要直接写入响应体。
  • @ReuqestMapping修饰Controller层的类,定义其相对路径,不同方法内再用@PostMapping等定义下一级路径
  • @RequestBody修饰Controller层方法的形参,自动将参数从JSON转换成相应的对象。
  • 在Controller层,基本只做对参数的校验和调Service层接口,做到尽量的解耦

1.3.3 实现

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @PostMapping("/register")
    public Long userRegister(@RequestBody UserRegisterRequest userRegisterRequest){
        if(userRegisterRequest == null){
            return null;
        }
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();

        if(StringUtils.isAnyBlank(userAccount,userPassword,checkPassword)){
            return null;
        }
        return userService.userRegister(userAccount, userPassword, checkPassword);
    }

    @PostMapping("/login")
    public User userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request){
        if(userLoginRequest == null){
            return null;
        }
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();

        if(StringUtils.isAnyBlank(userAccount,userPassword)){
            return null;
        }
        return userService.userLogin(userAccount, userPassword, request);
    }

}

1.3.4 测试

可以用IDEA自带的测试工具:

  1. 点击对应方法左边的http客户端打开

  2. 写请求头和参数

    json 复制代码
     POST http://localhost:8080/user/login
     Content-Type: application/json
    
     {
       "userAccount" : "lzj33",
       "userPassword" : "123456789"
     }
  3. 启动后端服务器,发送请求,配合断点调试和查看返回值

2. 管理员逻辑

2.1接口文档

2.1.1 根据用户名查询用户

  • 接收参数:用户名
  • 接收参数类型:String
  • 请求类型:GET
  • 请求体类型:String
  • 返回值:List<User> 用户信息(脱敏)

2.1.2 根据用户id删除用户

  • 接收参数:用户id
  • 接收参数类型:int
  • 请求类型:POST
  • 请求体类型:int
  • 返回值:boolean是否删除成功

2.2 知识点

  • 需要做用户鉴权,从session中取出当前登录用户的信息,判断是否为管理员(userRole==1)
  • 返回的用户信息需要脱敏
  • 重复的代码(10行以上)提取为方法,如两个接口都有用户鉴权,可以提取为公共方法提高代码复用性
  • 常量可以提取到一个接口中存储

2.3 实现

2.3.1 用户鉴权

java 复制代码
public boolean isAdmin(HttpServletRequest request){
    Object userObj = request.getSession().getAttribute(USER_LOG_STATE);
    User user = (User)userObj;
    if(user != null && user.getUserRole()==ADMIN_ROLE){
        return true;
    }
    return false;
}

2.3.2 用户脱敏

java 复制代码
public User getSafetyUser(User user){
    user.setUserPassword(null);
    return user;
}

2.3.3 查询和删除接口

java 复制代码
@GetMapping("/search")
public List<User> searchUsers(String userName, HttpServletRequest request){
    if(!isAdmin(request)){
        return null;
    }
    List<User> users = userService.searchUserByName(userName);

    return users;
}

@PostMapping("/delete")
public boolean deleteUser(@RequestBody long id, HttpServletRequest request){
    if(!isAdmin(request)){
        log.info("permission denied: not admin");
        return false;
    }
    if(id<=0){
        return false;
    }
    return userService.removeById(id);
}

3. 前端设置

前端使用ant-design pro脚手架快捷开发,页面原型已有,需要根据接口文档做一定修改

3.1 实现

3.1.1 修改请求

  1. 修改请求的路径,在api.ts中有各个接口对应的路径,修改成对应的后端路径
  2. 修改请求的参数:一个是前端中对应的变量名,还有一个是请求体真正传递的变量名
  3. 修改返回值的处理:由于后端返回的是user信息,将前端改成相应的处理(user是否为空)
  4. 修改代理:由于前端是8000端口,后端是8080端口,会有跨域问题。用其自带的代理配置可以完成跳转
  5. 后端全局路径配置:由于前端设置的请求路径是/api/xxx,后端需要给所有请求加一个/api的前缀,可以在application.xml中配置:
java 复制代码
server:
  port: 8080
  servlet:
    context-path: /api

3.2 测试

3.2.1 错误示例

3.2.2 成功示例

总结

  1. 后端三层架构下的接口开发、代码优化(冗余代码提取成方法、常量类)
  2. 常见SpringBoot注解的使用、Session的使用
  3. Mybatis-plus的使用,包括一键生成domain对象、mapper和service
  4. 后端测试:IDEA自带的http client,POST和GET的参数传递
  5. 断点测试:F7步入、F8逐步、F9恢复
  6. 前端代理和与后端参数、路径的对齐。
相关推荐
凡人的AI工具箱2 小时前
AI教你学Python 第11天 : 局部变量与全局变量
开发语言·人工智能·后端·python
是店小二呀2 小时前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
canonical_entropy2 小时前
金蝶云苍穹的Extension与Nop平台的Delta的区别
后端·低代码·架构
我叫啥都行3 小时前
计算机基础知识复习9.7
运维·服务器·网络·笔记·后端
无名指的等待7123 小时前
SpringBoot中使用ElasticSearch
java·spring boot·后端
.生产的驴4 小时前
SpringBoot 消息队列RabbitMQ 消费者确认机制 失败重试机制
java·spring boot·分布式·后端·rabbitmq·java-rabbitmq
AskHarries5 小时前
Spring Boot利用dag加速Spring beans初始化
java·spring boot·后端
苹果酱05675 小时前
一文读懂SpringCLoud
java·开发语言·spring boot·后端·中间件
掐指一算乀缺钱5 小时前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
计算机学姐8 小时前
基于python+django+vue的影视推荐系统
开发语言·vue.js·后端·python·mysql·django·intellij-idea