Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除

一.导学

  • 用户信息修改和删除服务

    • 常用的验证注解
    • 自定义消息
    • 自定义校验注解
  • 常用的验证注解

Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除
Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除

  • 扩展

http://hibernate.org/validator/documentation/
https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/

二.编写用户信息修改

  • 编写用户修改测试用例
	@Test
    public void whenUpdateSuccess() throws Exception{
        Date date = new Date(LocalDateTime.now().plusYears(1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());//传一个未来时间 加一年 时区
        String content = "{\"id\":\"1\",\"username\":\"playmaker\",\"password\":null,\"birthday\":"+date.getTime()+"}";
        String result = mockMvc.perform(MockMvcRequestBuilders.put("/user/1")
                       .contentType(MediaType.APPLICATION_JSON_UTF8)
                       .content(content))
                       .andExpect(MockMvcResultMatchers.status().isOk())
                       .andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1"))
                       .andReturn().getResponse().getContentAsString();
        System.out.println(result);
}

  • 编写用户修改接口
	 @PutMapping("/{id:\\d+}")
    public User update(@Valid  @RequestBody  User user ,BindingResult errors){
        if(errors.hasErrors()){
            errors.getAllErrors().stream().forEach(error-> {
                FieldError fieldError = (FieldError)error;
                String message = fieldError.getField()+" "+fieldError.getDefaultMessage();
                System.out.println(message);
            });
        }
        System.out.println(user.getId());
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getBirthday());

        user.setId("1");
        return user;
    }

	@NotBlank //不能为空
    private String password;
    @Past //必须是过去的时间
    private Date birthday;
  • 运行结果
    Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除
  • 说得不太具体,怎么控制错误消息?
  • 这些注解 都有一个共同属性 message来控制错误信息
  @NotBlank(message = "密码不能为空")
    private String password;
    @Past(message = "生日只能是过去的时间")
    private Date birthday;
  • 再次运行结果(这样就显而易见了)
    Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除
  • 很多时候提供的这些注解无法满足需求
  • 非常简单逻辑 最复杂就一个正则表达式
  • 有时候校验基于数据的 数据库存在嘛之类的
  • 自己写校验能够通过注解方式注入进来

三.自定义校验注解

  • 编写注解
@Target({ElementType.METHOD,ElementType.FIELD}) //标注可以在方法上 也可以在字段上
@Retention(RetentionPolicy.RUNTIME) //注解信息保留在运行时
@Constraint(validatedBy = MyConstraintValidator.class) //用于什么类注解这个注解,也就是有该注解的时候要执行的逻辑
public @interface MyConstraint {
     //下面三个方法是自定义校验注解必须的 如下图所示 message就是自定义验证信息
    String message() default "{javax.validation.constraints.NotBlank.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除

  • 编写校验逻辑
// 绑定一个注解类型,用于验证的值是什么
// 如果Object换成String,那么则只能把注解放在String类型上
//@Component
public class MyConstraintValidator implements ConstraintValidator<MyConstraint,Object> {
    //实现ConstraintValidator接口后,会被spring扫描管理,所以可以直接使用注入服务 所以不用再类上面加注解了
    @Autowired
    private HelloService helloService;//可以注入任何spring容器来完成你的校验逻辑 比如这个测试

    @Override
    public void initialize(MyConstraint constraintAnnotation) {//初始化方法
        System.out.println("init.....");
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {//注解要执行的校验逻辑
        helloService.greeting("tom");
        System.out.println(value);
        return false;//校验成功返回true 失败返回false
    }
}
  • 编写服务接口来测试
public interface HelloService {
        public String greeting(String name);
}
  • 实现类
@Service
public class HelloServiceImpl implements HelloService {
    @Override
    public String greeting(String name) {
        System.out.println("greeting...");
        return "hello "+name;
    }
}
  • 在User类username上添加这个注解
 @MyConstraint(message = "这是一个测试")
    private String username;
  • username上有这个,调用这个方法,把username值当value传进来

Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除

  • 运行结果
    Spring Security入门(七) 使用Spring MVC开发RESTful API-用户信息修改和删除
    总结:方便,自己定义一个注解,重用,免得去控制器里面反复写校验逻辑方便的多

四.删除服务

  • 编写测试类
 @Test
    public void whenDeleteSuccess() throws Exception{
        mockMvc.perform(MockMvcRequestBuilders.delete("/user/1")
        .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(MockMvcResultMatchers.status().isOk());

    }
  • 编写接口
@DeleteMapping("/{id:\\d+}")
    public void delete(@PathVariable String id){
        System.out.println(id);
    }