springboot苍穹外卖实战:三、新增员工(JWT令牌校验失败+用户名重复+ThreadLocal获取用户id解决方案)

新增员工

根据前端传递参数列表设计DTO

当前端提交的数据和实体类中对应的属性差别比较大时,建议使用DTO来封装数据。进入sky-pojo模块,在com.sky.dto包下,已定义EmployeeDTO。

EmployeeController

	/**
     * 新增员工
     * @param employeeDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增员工")
    public Result save(@RequestBody EmployeeDTO employeeDTO){
        log.info("新增员工:{}",employeeDTO);
        employeeService.save(employeeDTO);//该方法后续步骤会定义
        return Result.success();
    }

EmployeeService接口

	/**
     * 新增员工
     * @param employeeDTO
     */
    void save(EmployeeDTO employeeDTO);

EmployeeServiceImpl

	/**
     * 新增员工
     *
     * @param employeeDTO
     */
    public void save(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();

        //对象属性拷贝
        BeanUtils.copyProperties(employeeDTO, employee);

        //设置账号的状态,默认正常状态 1表示正常 0表示锁定
        employee.setStatus(StatusConstant.ENABLE);

        //设置密码,默认密码123456
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));

        //设置当前记录的创建时间和修改时间
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());

        //设置当前记录创建人id和修改人id
        employee.setCreateUser(10L);//目前写个假数据,后期修改
        employee.setUpdateUser(10L);

        employeeMapper.insert(employee);//后续步骤定义
    }

EmployeeMapper

	/**
     * 插入员工数据
     * @param employee
     */
    @Insert("insert into employee (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user,status) " +
            "values " +
            "(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})")
    void insert(Employee employee);

其实这里可以使用MybatisPlus进行改进。

测试

通过swagger页面进行接口测试,发现没有请求成功。
springboot苍穹外卖实战:三、新增员工(JWT令牌校验失败+用户名重复+ThreadLocal获取用户id解决方案)_第1张图片

JWT令牌校验失败

通过调试发现是JWT令牌校验失败的原因(这部分可以去看原视频,过程不好用图文描述),解决方法:调用员工登录接口获得一个合法的JWT令牌,然后将其添加到全局参数中。
文档管理–>全局参数设置–>添加参数。
springboot苍穹外卖实战:三、新增员工(JWT令牌校验失败+用户名重复+ThreadLocal获取用户id解决方案)_第2张图片
然后重启该swagger页面,发现测试成功。

用户名重复

Handler

com.sky.handler.GlobalExceptionHandler

 /**
     * 捕获SQL异常
     * @param ex
     * @return
     */
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        //Duplicate entry 'zhangsan' for key 'employee.idx_username'
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + MessageConstant.ALREADY_EXISTS;
            return Result.error(msg);
        }else{
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }

    }

Constant

com.sky.constant.MessageConstant新增

public static final String ALREADY_EXISTS = "已存在";

获取用户id(ThreadLocal)

ThreadLocal介绍与常用方法

ThreadLocal 并不是一个Thread,而是Thread的局部变量。
ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

  • public void set(T value) 设置当前线程的线程局部变量的值
  • public T get() 返回当前线程所对应的线程局部变量的值
  • public void remove() 移除当前线程的线程局部变量

定义ThreadLocal工具类

com.sky.context.BaseContext已经定义好

JwtTokenAdminInterceptor中设置id

com.sky.interceptor.JwtTokenAdminInterceptor

//2、校验令牌
        try {
            log.info("jwt校验:{}", token);
            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
            log.info("当前员工id:", empId);
            //3、通过,放行

            BaseContext.setCurrentId(empId);

            
            return true;

EmployeeServiceImpl中获取id

com.sky.service.impl.EmployeeServiceImpl

        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());

你可能感兴趣的:(spring,boot,后端,java,web,springboot,spring)