学习springboot项目笔记

基于b站springboot3+vue3的项目学习

获取用户详细信息

1根据用户名查询用户

1.实现思路
因为url路径中的请求参数为控制,因此需要从登录功能中封装的token解析用户名

  • 第一步是使用@Request Header主键,将token添加到方法参数中
  • 调用jwt工具类的parsetoken,此方法会按照设置好的key进行反向解析,将信息封装到Map类型中
  • 调用get获取username
  • 最后调用service层中的findbyusername方法
  • 完成
    2.优化思路
    解决代码复用性高的问题
  • 使用Threadlocal工具类
  • 在拦截器中进行令牌验证时,验证token后
  • 调用threadlocal的set方法储存 对象值claims
  • 在controller中调用thread local的get方法
Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String)map.get("username");

3.解释一下Threadlocal

  • 我的理解:是一个工具,为一个用户分配一个线程,只要用户的状态允许,我们就可以在任何地方通过线程获取用户的信
  • 下面是gpt的解释:
    – ThreadLocal 是 Java 中的一个工具类,它提供了线程局部变量的功能。简单来说,ThreadLocal 允许您在每个线程中存储和获取独立的变量,而不会与其他线程的变量产生冲突。

以下是 ThreadLocal 的一些关键特点和用法:

独立存储: 每个线程都有自己的变量副本,线程之间互不影响。
线程隔离: 可以将数据与线程关联起来,使得数据在整个线程生命周期内可用,但不会被其他线程访问。
线程安全: ThreadLocal 内部使用了线程封闭技术,确保了数据的线程安全性。
简化线程共享: 适用于需要在多个方法或类中传递数据,但又不想使用方法参数传递的情况。
避免传递参数: 可以避免将上下文数据作为方法参数传递,从而简化代码,提高可读性和可维护性。

完成这个共呢个遇见的bug

1.jwt依赖版本过低问题,会导致工具类中的方法失效
2.最2b的bug,重新获取token,因为拦截器的excludePathPatterns(“/user/login”,“/user/register”);
路径设置错误,导致登录页面也被拦截

2更新用户基本信息

基本信息更新

1.controller层调用service的update方法,在impl实现方法的具体业务逻辑
2.调用持久层mapper的update方法,添加@Update注解,完成
3.实体参数的校验

  • 在实体类的成员变量中添加注解
    – @Notnull
    – @NotEmpty
    – Email
@NotNull
private Integer id;//主键ID
private String username;//用户名
@JsonIgnore
private String password;//密码
@NotEmpty
@Pattern(regexp = "^\\S{1,10}$")
private String nickname;//昵称
@NotEmpty
@Email
private String email;//邮箱
  • 在controller接口方法上添加@Validated注解

更新头像

主要注意的是参数限制,使用@URL注解验证url地址是否正确

修改密码

@RequestBody注解 将前端传过来的json转换为map类型

  • 校验参数
String oldPwd = params.get("old_pwd");
String newPwd = params.get("new_pwd");
String re = params.get("re_pwd");

if(!StringUtils.hasLength(oldPwd)||!StringUtils.hasLength(newPwd)||!StringUtils.hasLength(re)){
    return Result.error("缺少必要的参数");
}
//调用userService根据用户名拿到原密码,再和oldpwd比对
Map<String,Object> map = ThreadLocalUtil.get();
String username = (String)map.get("username");
User loginuser = userService.findByUserName(username);
        if(!loginuser.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return Result.error("原密码填写不正确");
        }
  • 调用service的updatePwd方法
  • 最后调用mapper的updatePwd方法,写入update sql语句完成

文章分类

新增文章分类

很重要的一个点,进行参数校验
因为前端给的json数据只有两个,所以其他的参数需要在impl层中手动添加

category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        category.setCreateUser(id);
        // 因为id在前端中也没有要求
        // 所以在impl中添加
    mapper层代码
    /**
     * 添加图书分类
     * @param category
     */
    @Insert("insert into category(category_name, category_alias, create_user, create_time, update_time)"+
            "values (#{categoryName},#{categoryAlias},#{createUser},#{createTime},#{updateTime})")
    void add(Category category);        
文章分类列表
  • 请求路径:当请求路径相同时,可以根据请求类型来进行分类
  • 响应结果:因为查看的结果是一个列表,所有Result的类型是一个Category类型的list集合
 public Result<List<Category>> list()
获取文章分类详情
更新文章分类

一个重点,定义分组,区分校验参数

  • 在实体类内部定义接口
  • 通过groups属性指定
  • 给@Validated注解的value属性赋值
  • 默认属于default分组
删除文章分类

文章相关接口

对草稿设置自定义注解

  • 自定义注解State
  • 自定义校验数据的类StateValidation
  • 在需要校验的地方使用自定义注解
    eg:
    1.自定义注解State
@Documented//元注解
@Constraint(validatedBy = {Statevalidation.class})//指定需要检验规则的类
@Target({ElementType.FIELD,})
@Retention(RUNTIME)

public @interface State {

    //提供校验失败后的提示信息
    String message() default "{state参数的值只能是已发布或草稿}";

    //指定分组
    Class<?>[] groups() default {};

    //负载 获取到State注解的附加信息
    Class<? extends Payload>[] payload() default {};
}

2.自定义校验数据的类StateValidation

public class Statevalidation implements ConstraintValidator<State,String> {
    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        //提供校验规则
        if(s == null){
            return false;
        }
        if(s.equals("已发布")||s.equals("草稿")){
            return true;
        }
        return false;
    }
}

使用pagehelper插件完成
1.对反回结果的类型处理

    public Result<PageBean<Article>> list()

2.充分封装一个类pagebean,有两个变量total总条数 和 items数据集合,这个类的泛型是一个文章类
3.在serviceImpl中开启分页查询

//创建pageBean对象
        PageBean<Article> pb = new PageBean<>();
        //开启分页查
        PageHelper.startPage(pageNum,pageSize);

        //查询当前用户id
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        //调用mapper
        List<Article> as = articleMapper.list(userId,categoryId,state);
        Page<Article> p = (Page<Article>) as;
        //把数据填充到PageBean对象中
        pb.setTotal(p.getTotal());
        pb.setItems(p.getResult());
        return pb;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值