【第7章】SpringBoot实战篇之用户详细信息

文章目录

  • 前言
  • 一、获取用户详细信息
    • 1. ThreadLocalUtil
    • 2. LoginInceptor
    • 3. UserController1
    • 4. 测试
  • 二、更新用户基本信息
    • 1.ValidatedGroups
    • 2.User
    • 3. UserController1
    • 4. service
    • 5. 测试
      • 1. 参数校验
      • 2. 更新测试
  • 三、更新用户头像
    • 1. UserController1
    • 2. 测试
  • 四、更新用户密码
    • 1. UserController1
    • 2. service
    • 3. 测试
  • 总结


前言

本章节主要介绍用户信息的获取、更新和更新用户头像及用户密码。


一、获取用户详细信息

1. ThreadLocalUtil

package org.example.springboot3.bigevent.utils;


/**
 * ThreadLocal 工具类
 */
@SuppressWarnings("all")
public class ThreadLocalUtil {
    //提供ThreadLocal对象,
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();

    //根据键获取值
    public static <T> T get(){
        return (T) THREAD_LOCAL.get();
    }
	
    //存储键值对
    public static void set(Object value){
        THREAD_LOCAL.set(value);
    }


    //清除ThreadLocal 防止内存泄漏
    public static void remove(){
        THREAD_LOCAL.remove();
    }
}

2. LoginInceptor

package org.example.springboot3.bigevent.inceptors;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.springboot3.bigevent.entity.Result;
import org.example.springboot3.bigevent.utils.JwtUtils;
import org.example.springboot3.bigevent.utils.ThreadLocalUtil;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Create by zjg on 2024/5/26
 */
@Component
public class LoginInceptor implements HandlerInterceptor {
    private Map<Integer,String> loginUsers=new ConcurrentHashMap<>(256);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        if(token!=null&&token.contains("Bearer")){
            String tokenStr = token.substring(token.indexOf("Bearer") + 7);
            boolean verify = JwtUtils.verify(tokenStr);
            if(verify){//此处解析loginUsers,验证用户已登录
                Map<String, Object> claims = JwtUtils.getClaims(tokenStr);
                if(tokenStr.equals(this.get((Integer) claims.get("userId")))){
                    ThreadLocalUtil.set(claims);//用户信息放置ThreadLocal
                    return true;
                };
            }
        }
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType("application/json;charset=UTF-8");
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.writerFor(Result.class);
        String message = objectMapper.writeValueAsString(Result.error("token验证失败,请重新获取token后重试!"));
        response.getWriter().println(message);
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        ThreadLocalUtil.remove();
    }

    public String put(Integer id, String token){
        return loginUsers.put(id, token);
    }
    public String get(Integer id){
        return loginUsers.get(id);
    }
    public String remove(Integer id){
        return loginUsers.remove(id);
    }

}

3. UserController1

package org.example.springboot3.bigevent.controller;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Pattern;
import org.example.springboot3.bigevent.entity.Result;
import org.example.springboot3.bigevent.entity.User;
import org.example.springboot3.bigevent.inceptors.LoginInceptor;
import org.example.springboot3.bigevent.service.UserSerivce;
import org.example.springboot3.bigevent.utils.JwtUtils;
import org.example.springboot3.bigevent.utils.Md5Util;
import org.example.springboot3.bigevent.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

/**
 * Create by zjg on 2024/5/22
 */
@RequestMapping("/user/")
@RestController
@Validated
public class UserController1 {
    @Autowired
    LoginInceptor loginInceptor;
    @Autowired
    UserSerivce userSerivce;
    @RequestMapping("login")
    public Result login(@Valid User loginUser){
        String message="用户名/密码不正确";
        User user = userSerivce.findUserByName(loginUser.getUsername());
        if(user!=null){//用户存在
            if(user.getPassword().equals(Md5Util.getMD5String(loginUser.getPassword()))){//密码正确
                Map<String,Object> claims=new HashMap();
                claims.put("userId",user.getId());
                claims.put("username",user.getUsername());
                String token = JwtUtils.create(claims);
                loginInceptor.put(user.getId(),token);
                return Result.success("登录成功",token);
            }
        }
        return Result.error(message);
    }

    @RequestMapping("info")
    public Result info(){
        Map<String, Object> claims =ThreadLocalUtil.get();
        String Username = (String) claims.get("username");
        User user = userSerivce.findUserByName(Username);
        if(user==null){
            String message="用户不存在";
            return Result.error(message);
        }
        return Result.success(user);
    }
}

4. 测试

二、更新用户基本信息

前面我们新注册用户的时候,使用了参数校验,这里更新我们需要进行参数校验分组和注册的参数区分

1.ValidatedGroups

package org.example.springboot3.bigevent.valid;

/**
 * Create by zjg on 2024/5/26
 */
public class ValidatedGroups {
    public interface Insert{};
    public interface Delete{};
    public interface Update{};
    public interface Selete{};
}

2.User

package org.example.springboot3.bigevent.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.example.springboot3.bigevent.valid.ValidatedGroups;

import java.time.LocalDateTime;


@Getter
@Setter
@ToString
public class User {
    @NotNull(message = "id 不能为空",groups = ValidatedGroups.Update.class)
    @TableId(type=IdType.AUTO)
    private Integer id;//主键ID
    @Pattern(regexp = "^\\S{6,20}$",message = "用户名长度为6-20位")
    private String username;//用户名
    @Pattern(regexp = "^\\S{8,20}$",message = "密码为8-20位")
    @JsonIgnore
    private String password;//密码
    @NotEmpty(message = "昵称不能为空",groups = ValidatedGroups.Update.class)
    private String nickname;//昵称
    @Email(message = "请输入正确的邮箱格式",groups = ValidatedGroups.Update.class)
    @NotEmpty(message = "邮箱不能为空",groups = ValidatedGroups.Update.class)
    private String email;//邮箱
    private String userPic;//用户头像地址
    private LocalDateTime createTime;//创建时间
    private LocalDateTime updateTime;//更新时间
}

3. UserController1

package org.example.springboot3.bigevent.controller;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Pattern;
import org.example.springboot3.bigevent.entity.Result;
import org.example.springboot3.bigevent.entity.User;
import org.example.springboot3.bigevent.inceptors.LoginInceptor;
import org.example.springboot3.bigevent.service.UserSerivce;
import org.example.springboot3.bigevent.utils.JwtUtils;
import org.example.springboot3.bigevent.utils.Md5Util;
import org.example.springboot3.bigevent.utils.ThreadLocalUtil;
import org.example.springboot3.bigevent.valid.ValidatedGroups;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

/**
 * Create by zjg on 2024/5/22
 */
@RequestMapping("/user/")
@RestController
@Validated
public class UserController1 {
    @Autowired
    LoginInceptor loginInceptor;
    @Autowired
    UserSerivce userSerivce;
    @PutMapping("update")
    public Result update(@RequestBody @Validated(ValidatedGroups.Update.class) User user){
        int i=userSerivce.UpdateUser(user);
        if(i!=1){
            String message="更新失败";
            return Result.error(message);
        }
        return Result.success("更新成功");
    }
}

4. service

package org.example.springboot3.bigevent.service;

import org.example.springboot3.bigevent.entity.User;

/**
 * Create by zjg on 2024/5/22
 */
public interface UserSerivce {

    public int UpdateUser(User user) ;
}

package org.example.springboot3.bigevent.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.example.springboot3.bigevent.mapper.UserMapper1;
import org.example.springboot3.bigevent.entity.User;
import org.example.springboot3.bigevent.service.UserSerivce;
import org.example.springboot3.bigevent.utils.Md5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;

/**
 * Create by zjg on 2024/5/22
 */
@Service
public class UserSerivceImpl implements UserSerivce {
    @Autowired
    UserMapper1 userMapper1;
    @Override
    public int UpdateUser(User user) {
        user.setUpdateTime(LocalDateTime.now());
        return userMapper1.updateById(user);
    }
}

5. 测试

1. 参数校验

在这里插入图片描述

2. 更新测试

更新结果
在这里插入图片描述

更新之前
在这里插入图片描述

更新之后

在这里插入图片描述

三、更新用户头像

1. UserController1

@RequestMapping("/user/")
@RestController
@Validated
public class UserController1 {
/**
     * 更新用户头像
     * @param avatar 图片地址
     * @return 结果
     */
    @PatchMapping("avatar")
    public Result avatar(@RequestParam @URL String avatar){
        Map<String, Object> claims =ThreadLocalUtil.get();
        Integer userId = (Integer) claims.get("userId");
        User user = new User();
        user.setId(userId);
        user.setUserPic(avatar);
        int i=userSerivce.UpdateUser(user);
        if(i!=1){
            String message="更新头像失败";
            return Result.error(message);
        }
        return Result.success("更新头像成功");
    }
}

2. 测试

在这里插入图片描述

四、更新用户密码

1. UserController1

@RequestMapping("/user/")
@RestController
@Validated
public class UserController1 {
    @Autowired
    LoginStorage loginStorage;
    @Autowired
    UserSerivce userSerivce;
    /**
     * 更新用户密码
     * @param params 密码
     * @return 结果
     */
    @PatchMapping("updatePwd")
    public Result updatePwd(@RequestBody Map<String,String> params){
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String conPwd = params.get("con_pwd");
        //参数校验
        if(!StringUtils.hasLength(oldPwd)||!StringUtils.hasLength(newPwd)||!StringUtils.hasLength(conPwd)){
            return Result.error("缺少必要的参数");
        }
        if(!validPwdLen(oldPwd)||!validPwdLen(newPwd)||!validPwdLen(conPwd)){
            return Result.error("密码为8-20位");
        }
        //密码匹配
        Map<String, Object> claims =ThreadLocalUtil.get();
        Integer userId = (Integer) claims.get("userId");
        User user = userSerivce.findUserById(userId);
        if(!Md5Util.getMD5String(oldPwd).equals(user.getPassword())){
            return Result.error("密码有误");
        }
        //新密码匹配
        if(!newPwd.equals(conPwd)){
            return Result.error("两次密码不匹配");
        }
        //新旧匹配
        if(newPwd.equals(oldPwd)){
            return Result.error("新旧密码不能相同");
        }
        user.setPassword(Md5Util.getMD5String(newPwd));
        int i = userSerivce.UpdateUser(user);
        if(i!=1){
            return Result.success("密码修改失败");
        }
        loginStorage.remove(user.getId().toString());
        return Result.success("密码修改成功");
    }
}

2. service

package org.example.springboot3.bigevent.service;

import org.example.springboot3.bigevent.entity.User;

/**
 * Create by zjg on 2024/5/22
 */
public interface UserSerivce {

    public int UpdateUser(User user) ;

    public User findUserById(Integer userId);
}

@Service
public class UserSerivceImpl implements UserSerivce {
    @Autowired
    UserMapper1 userMapper1;
    @Override
    public int UpdateUser(User user) {
        user.setUpdateTime(LocalDateTime.now());
        return userMapper1.updateById(user);
    }
    @Override
    public User findUserById(Integer userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", userId);
        return userMapper1.selectOne(queryWrapper);
    }
}

3. 测试

在这里插入图片描述


总结

回到顶部

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/684126.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RAD和TOT效率

最近在用CST仿真天线&#xff0c;如下自己建了一个倒F的蓝牙天线&#xff1a; 然后使用波导端口给予激励&#xff0c;大概仿真的S参数如下&#xff1a; 同时查看CST仿真效率图中发现有两个参数效率参数&#xff1a;RAD和TOT效率&#xff0c;如下&#xff1a; 具体是什么意思呢&…

设计模式之观察者模式ObserverPattern(十一)

一、概述 观察者模式 (Observer Pattern) 是一种行为型设计模式&#xff0c;又被称为发布-订阅 (Publish/Subscribe) 模式&#xff0c;它定义了对象之间的一种一对多的依赖关系&#xff0c;使得当一个对象的状态发生变化时&#xff0c;所有依赖于它的对象都会自动收到通知并更新…

云原生架构案例分析_1.某旅行公司云原生改造

随着云计算的普及与云原生的广泛应用&#xff0c;越来越多的从业者、决策者清晰地认识到“云原生化将成为企业技术创新的关键要素&#xff0c;也是完成企业数字化转型的最短路径”。因此&#xff0c;具有前瞻思维的互联网企业从应用诞生之初就扎根于云端&#xff0c;谨慎稳重的…

2年JAVA今日头条3轮面试经历

面头条的时候已经是十月底了。大半个月没有面试&#xff0c;之前准备的知识点比如http状态码之类的记忆性的东西&#xff0c;早就忘光了。 二面的时候问了一堆状态码&#xff0c;全都不记得了。面试官态度很好&#xff0c;跟我说&#xff0c;你现在不记得了&#xff0c;说明你…

STM32远程更新

1 IAP 概述 1.1 工作原理 在应用中编程&#xff08; IAP &#xff09;是一种在现场通过 MCU 的通信接口&#xff08;例如 UART,USB,CAN 和以太网 等&#xff09;进行固件升级的方式。 当启动微控制器时&#xff0c;您可以选择让它进入 IAP 模式以执行 IAP 代码&am…

企业级数据保护:华企盾DSC敏感内容识别与加密技术

在当今数字化时代&#xff0c;企业面临的数据安全挑战日益严峻。敏感数据的泄露不仅会导致经济损失&#xff0c;还可能损害企业的声誉和客户信任。因此&#xff0c;采用先进的敏感内容识别和加密技术&#xff0c;例如华企盾DSC敏感内容识别&#xff0c;对企业数据进行有效保护至…

PyCharm如何更换解析器为Anaconda,如何自己切换python环境

自己使用了Anaconda创建了一个环境&#xff1a; 如何在工具PyCharm中切换自定义的python环境呢&#xff1f; 1. 点击 设置 2. 项目&#xff1a;python - Python解析器 此时会发现&#xff0c;只有一个默认的版本。 3. 点击 添加解析器 - 添加本地解析器 4. 选择 conda 环境…

全球AI新闻速递6.6

1.伏羲升级&#xff01;智能气象创新生态联盟成立。 2.微软&#xff1a;首个大规模大气基础模型Aurora。 3.鸿海集团&#xff1a;宣布在高雄建造先进算力中心&#xff0c;与NVIDIA在 AI 领域合作展开多方面合作。 4.全球首个全切片数字病理学模型GigaPath发布。 5.OpenAI与…

DDS自动化测试落地方案 | 怿星科技携最新技术亮相是德科技年度盛会

5月28日&#xff0c;怿星科技作为是德科技的重要合作伙伴亮相Keysight World Tech Day 2024。在此次科技盛会上&#xff0c;怿星科技不仅展示了领先的DDS自动化测试解决方案等前沿技术&#xff0c;还分享了在“周期短、任务重”的情况下&#xff0c;如何做好软件开发和测试验证…

指纹考勤机的运用办法,指纹考勤机一台多少钱

指纹考勤机的运用办法&#xff0c;指纹考勤机一台多少钱 通常普通的指纹考勤机仅需几十元到一百元上下&#xff0c;只具备单纯的打卡功能&#xff0c;使用体验较差&#xff1b;这种考勤机仅有基础的指纹打卡时间记录&#xff0c;拷贝需要 U 盘&#xff0c;整理则需人员进…

多曝光融合算法(三)cv2.createAlignMTB()多曝光图像融合的像素匹配问题

文章目录 1.cv2.createAlignMTB() 主要是计算2张图像的位移&#xff0c;假设位移移动不大2.多曝光图像的aline算法&#xff1a;median thresold bitmap原理讲解3.图像拼接算法stitch4.多曝光融合工具箱 1.cv2.createAlignMTB() 主要是计算2张图像的位移&#xff0c;假设位移移动…

EXCEL从图片链接获取图片

step1: 选中图片地址列 step2:开发工具→Visual Basic 文件→导入 导入我制作的脚本&#xff08;代码见文章末尾&#xff09; 点击excel的小图标回到表格界面。 点击【宏】 选中刚才导入的脚本&#xff0c;点执行&#xff0c;等待完成。 代码本体&#xff1a; Sub InsertPict…

数据结构与算法-12_二叉搜索树

文章目录 1.概述2.实现定义节点查询Comparable最小最大新增前驱后继删除找小的找大的找之间小结 3.习题E01. 删除节点-Leetcode 450E02. 新增节点-Leetcode 701E03. 查询节点-Leetcode 700E04. 验证二叉搜索树-Leetcode 98E05. 求范围和-Leetcode 938E06. 根据前序遍历结果构造…

VB.net实战(VSTO):Excel插件的安装与卸载

1. 安装 1.1编程环境&#xff1a;Visual Studio 2022 1.2创建新项目&#xff1a; 1.3 加入一行测试程序&#xff1a;MsgBox&#xff08;“hello”&#xff09;&#xff0c;点击启动&#xff0c;确认可以弹窗 1.4 点击发布 1.5 找到安装程序&#xff0c;点击安装。打开Excel程…

XM平台的交易模式模式是什么?

外汇交易平台的盈利模式主要分为两种&#xff1a;有交易员平台和无交易员平台。 有交易员平台&#xff0c;也称为做市商平台&#xff0c;为客户提供交易市场&#xff0c;并在需要时与客户持相反方向的交易&#xff0c;从中赚取利润。交易者看到的买入卖出价可能与实际价格不同&…

Android完整备份:备份Android手机数据的4种最佳方法

如今&#xff0c;人们每天都依赖手机&#xff0c;丢失数据对我们所有人来说都是一个大麻烦。由于生活是不可预测的&#xff0c;没有人知道什么时候他的数据可能会被意外删除或丢失。因此&#xff0c;仔细备份手机数据非常重要。大多数主要智能手机平台都具有将数据备份到计算机…

在Win10安装MySQL环境以及更改相关配置---附带每一步截图

下载MySQL数据库 MySQL官网链接 选择合适自己的版本&#xff0c;这里我选择5.7.17&#xff0c;选择安装包大的那一个&#xff0c;这个是离线安装&#xff0c;下载到本地后进行安装。 选择“No thanks&#xff0c;just start my download.”即进入下载状态。 安装 运行安…

JavaSE——【方法的使用】(二)

文章目录 前言一、方法重载二、递归总结 前言 在无尽的宇宙深处&#xff0c;一艘造型奇特的飞船如流星般划过黑暗。飞船内部&#xff0c;各种高科技设备闪烁着冷峻的光芒。一位年轻的宇航员正专注地操作着控制面板&#xff0c;面板上突然弹出JavaSE—方法的使用的续篇更新了&am…

【Python Cookbook】S01E20 fnmatch 模块做字符串匹配

目录 问题解决方案讨论 问题 在不同的操作系统下&#xff0c;怎样做字符串匹配&#xff1f; 解决方案 fnmatch() 模块提供两个函数&#xff0c;fnmatch() 以及 fnmatchcase() 可以用来执行做这样的匹配。 from fnmatch import fnmatch, fnmatchcasematch_res fnmatch(foo.…

MBR10100FCT-ASEMI肖特基二极管MBR10100FCT

编辑&#xff1a;ll MBR10100FCT-ASEMI肖特基二极管MBR10100FCT 型号&#xff1a;MBR10100FCT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;10A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1…