<从零学习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. 前端代理和与后端参数、路径的对齐。
相关推荐
苏三说技术2 小时前
xxl-job 和 elastic-job,哪个更好?
后端
三小河3 小时前
Agent Skill与Rules的区别——以Cursor为例
前端·javascript·后端
三小河3 小时前
前端视角详解 Agent Skill
前端·javascript·后端
牛奔3 小时前
Go 是如何做抢占式调度的?
开发语言·后端·golang
颜酱3 小时前
二叉树遍历思维实战
javascript·后端·算法
爱装代码的小瓶子3 小时前
【C++与Linux基础】进程间通讯方式:匿名管道
android·c++·后端
程序员良许4 小时前
嵌入式处理器架构
后端·单片机·嵌入式
MrSYJ4 小时前
Redis 做分布式 Session
后端·spring cloud·微服务
Cache技术分享4 小时前
318. Java Stream API - 深入理解 Java Stream 的中间 Collector —— mapping、filtering 和 fla
前端·后端
Elieal4 小时前
SpringBoot 数据层开发与企业信息管理系统实战
java·spring boot·后端