文章目录
前言
本章节主要介绍用户信息的获取、更新和更新用户头像及用户密码。
一、获取用户详细信息
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);
}
}