Springboot菜鸟日记 第二天

第二天

@Jsonignore

private Integer id;//主键ID
private String username;//用户名
@JsonIgnore//让springmvc把当前对象转换成json字符串的时候忽略password
private String password;//密码
private String nickname;//昵称

当接口返回一个对象时,可以选择性的将一些属性忽略,注意它的包名,选错了不起作用

数据库用的是下划线,实体类用的是驼峰命名,需要修改mybatis的配置,即可自动识别,例如createTime与create_time

mybatis:
  configuration:
    map-underscore-to-camel-case: true #开启驼峰与下划线自动转换

ThreadLocal 线程局部变量

 void testThreadLocalSetAndGet(){
    ThreadLocal tl =new ThreadLocal();
    new Thread(()->{
      tl.set(1);
      System.out.println(Thread.currentThread().getName()+tl.get());
      System.out.println(Thread.currentThread().getName()+tl.get());
      System.out.println(Thread.currentThread().getName()+tl.get());
    },"蓝色").start();
    
   new Thread(()->{
    tl.set(2);
    System.out.println(Thread.currentThread().getName()+tl.get());
    System.out.println(Thread.currentThread().getName()+tl.get());
    System.out.println(Thread.currentThread().getName()+tl.get());
  },"绿色").start();
}

蓝色1 蓝色1 蓝色1 绿色2 绿色2 绿色2

线程之间互不干扰

可以在拦截器中生成一个线程局部变量,将jwt解析出来的身份信息存入线程变量,此时其他层需要使用此变量时,直接使用get即可

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception {
  //令牌验证
  String token = request.getHeader("Authorization");
  try {
    Map<String, Object> claims = JwtUtil.parseToken(token);
    //把业务数据存储到ThreadLocal中
    ThreadLocalUtil.set(claims);
    return true;//放行
  }catch (Exception e){
    response.setStatus(401);
    return false;//不放行
  }
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response ,Object handler,Exception ex) throws Exception{
    ThreadLocalUtil.remove();
  }

当所有使用之后,会自动调用afterCompletion函数,将此变量进行清楚,防止内存泄漏

参数校验

@NotNull
private Integer id;//主键ID
private String username;//用户名
@JsonIgnore//让springmvc把当前对象转换成json字符串的时候忽略password
private String password;//密码
@NotEmpty
@Pattern(regexp = "^//S{1,10}")
private String nickname;//昵称
@NotEmpty
@Email
private String email;//邮箱
private String userPic;//用户头像地址
private LocalDateTime createTime;//创建时间
private LocalDateTime updateTime;//更新时间

在实体类中的属性上方写注解@NotNull 值不能为null @NotEmpty 值不能为null,且内容不能为空 @Email 满足邮箱格式 还有@Pattern ,可以对接口传递的参数进行参数校验

@PutMapping("/update")
public Result update(@RequestBody @Validated User user){
  userservice.update(user);
return  Result.success();
}

想要进行参数校验时,必须在前面使用@Validated,不使用不生效

@PatchMapping("/updateAvatar")
public Result updateAvatar(@RequestParam @URL String avatarUrl){
 userservice.updateAvatar(avatarUrl);
 return  Result.success();
}
​
"code": 1,
    "message": "updateAvatar.avatarUrl: 需要是一个合法的URL",
    "data": null

@URL,用来参数校验url地址

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;//创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;//更新时间

@JsonFormat 用于规范格式,主要用于时间。

分组校验

@NotNull
private Integer id;//主键ID
@NotEmpty
private String categoryName;//分类名称
@NotEmpty
private String categoryAlias;//分类别名
private Integer createUser;//创建人ID
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;//创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;//更新时间

这是简单的参数校验,看似没有问题,实则会有bug,update需要id,但是add时并不需要id,数据库自动生成,所以如果给id写@NotNull注解时,我们的add接口就会报错,所以我们需要进行分组,当update时注解生效,add时注解不生效

第一步,在实体类中写要分的组,就是写出空白接口即可

public interface  Add{
​
}
​
public  interface  Update{
​
}

第二步,在参数的注解后面写上函数所需要的接口

@NotNull(groups = Update.class)
private Integer id;//主键ID
@NotEmpty(groups = {Update.class,Add.class})
private String categoryName;//分类名称
@NotEmpty(groups = {Update.class,Add.class})
private String categoryAlias;//分类别名
private Integer createUser;//创建人ID
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;//创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;//更新时间

第三步,在controller函数的validated后面加上所需要的接口

@PutMapping("/update")
public Result update(@RequestBody @Validated(Update.class) Category category)
{
  categoryService.update(category);
  return  Result.success();
}
@PostMapping("/add")
    public Result add(@RequestBody @Validated(Add.class) Category category){
      categoryService.add(category);
      return Result.success();
    }

当然,如果所需要的函数特别多,就需要默认分组以及继承

//如果某个校验项没有指定分组,默认属于Default分组
//分组之间可以继承,A extends B A中拥有B中所有额度校验项
@NotNull(groups = Update.class)
private Integer id;//主键ID
@NotEmpty
private String categoryName;//分类名称
@NotEmpty
private String categoryAlias;//分类别名
private Integer createUser;//创建人ID
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;//创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;//更新时间
​
//如果某个校验项没有指定分组,默认属于Default分组
//分组之间可以继承,A extends B A中拥有B中所有额度校验项
public interface  Add extends Default {
​
}
​
public  interface  Update extends Default{
​
}

把分类名称和分类别名后面的括号删了,直接继承也可以起到相同的作用

小结

今天再次加深了Springboot的使用,jwt的使用和线程变量的使用,觉得这两个还是有一点抽象的,暂时没有完全理解,但是简单的使用是学会了的,觉得线程变量确实挺好用,以及一些参数校验的使用和注解的使用,可以自己写出几个简单的业务,如增删改查等,但是还是有一些细节会忽略,例如参数格式没有进行判断,还有就是不能对不同类型的接口的不同参数进行直接判断,application/json或者x-www-form-urlencoded还有queryString不够熟悉,需要查阅资料或者查看之前的,明天主要记忆一下这些接口,可以直接写出来,节省时间,还有就是今天复习了一下mysql的使用,现在可以接触到的大都是一些简单的sql语句,简单的增删改查等,简单复习了一下,过几天再认真复习一下mysql的使用,争取把自己之前的水平找到吧,今天就这样,进度还是比较满意的,不过就是这几天过的速度太快了,没有及时的复习,等把这节实战课上完了,我想自己再写一个项目,全部复习过一遍,效果应该会好一点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值