第二天
@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的使用,争取把自己之前的水平找到吧,今天就这样,进度还是比较满意的,不过就是这几天过的速度太快了,没有及时的复习,等把这节实战课上完了,我想自己再写一个项目,全部复习过一遍,效果应该会好一点。