Spring MVC注解@Valid、@JsonSerialize、@JsonView等

这篇博客介绍了Spring MVC中用于校验的@Valid注解,包括简单校验和自定义校验器的使用。同时,文章探讨了JSON序列化相关注解@JsonView,如何通过它来选择性地序列化对象字段。另外,还提到了@JsonIgnore和@JsonIgnoreProperties注解在防止字段序列化时的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


@Valid

Spring MVC采用的校验是hibernate-validate,第一步肯定是导包,就忽略了

可使用的校验注解

@NotNull  值不能为空
@Null     值必须为空
@Pattern(regex=) 字符串必须匹配正则表达式
@Size(min=,max=)  集合的元素数量必须在min和max之间
@CreditNumber(ignoreNonDigitCharacters=) 字符串必须是信用卡号(按美国的标准验证)
@Email    字符串必须是Email地址
@Length(min=,max=) 检查字符串的长度
@NotBlank   字符串必须有字符
@Range(min=,max=) 数字必须大于min,小于等于max
@SafeHtml   字符串是安全的html
@URL   字符串是合法的URL
@AssertFalse   值必须是false
@AssertTrue    值必须是true
@DecimalMax(value,inclusive=) 值必须小于等于(inclusive=true)/小于(inclusive=false) value属性指定的值,可以注解在字符串类型的属性上
@DecimalMin(value,inclusive=) 值必须大于等于(inclusive=true)/大于(inclusive=false) value属性指定的值,可以注解在字符串类型的
属性上
@Digits(integer=,fraction=)  数字格式检查,integer指定整数部分的最大长度,fraction指定小数部分的最大长度
@Future  值必须是未来的日志
@Past  值必须是过去的日期
@Max(value=) 值必须小于等于value指定的值,不能注视在字符串类型的属性上
@Min(value=) 值必须大于等于value指定的值,不能注视在字符串类型的属性上

简单的校验

用法,首先定义实体

public class User {

    private String id;

    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;

    @Past(message = "生日必须是过去的时间")
    private Date birthday;

  //getter and setter
}

控制层实现:
@PutMapping("/{id:\\d+}")
public User update(@Valid @RequestBody User user, BindingResult errors) {

    if(errors.hasErrors()){
        //errors.getAllErrors().stream().forEach( error -> System.out.println(error.getDefaultMessage()));
        errors.getAllErrors().stream().forEach( error ->{
            FieldError fieldError = (FieldError)error;
            System.out.println(fieldError.getField()+":"+fieldError.getDefaultMessage());
        });
    }

    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;
}

ok,错误信息就会打印出来,就可以做自己的逻辑处理了

自定义校验器校验

/**
 * 自定义的校验器
 * Created by xingyuchao on 2017/12/2.
 */
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
	
	String message();

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

	Class<? extends Payload>[] payload() default { };
	
	String field() default "";
}
上面那三个属性是必须的

完成校验逻辑,需要注意的是实现了ConstraintValidator的类已经在spring容器中了,因此可以使用注入其它类了
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, Object> {

	@Autowired
	private HelloService helloService;
	
	@Override
	public void initialize(MyConstraint constraintAnnotation) {
		System.out.println("my validator init");
	}

	@Override
	public boolean isValid(Object value, ConstraintValidatorContext context) {
		helloService.greeting("tom");
		System.out.println(value);
		return false;  //返回true则校验通过,false校验不通过
	}

}

使用
private String id;

@MyConstraint(message = "这是一个校验测试")
private String username;

@NotBlank(message = "密码不能为空")
private String password;

@Past(message = "生日必须是过去的时间")
private Date birthday;

@JsonView

@JsonView可以过滤序列化对象的字段属性,可以使你有选择的序列化对象。


使用步骤:

  1. 使用接口来声明多个视图
  2. 在值对象的get方法上指定视图
  3. 在controller方法上指定视图

public class User {

    public interface UserSimpleView {};
    public interface UserDetailView extends UserSimpleView {};

    private String username;

    private String password;

    @JsonView(UserSimpleView.class)
    public String getUsername() {  return username; }

    public void setUsername(String username) { this.username = username;}

    @JsonView(UserDetailView.class)
    public String getPassword() {return password;}

    public void setPassword(String password) {this.password = password;}
}


@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping
    @JsonView(User.UserSimpleView.class)
    public List<User> query(UserQueryCondition condition,
                            @PageableDefault(page = 2, size = 17, sort = "username",direction= Sort.Direction.DESC) Pageable pageable){

        System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));   //打印toString

        System.out.println(pageable.getPageSize());
        System.out.println(pageable.getPageNumber());
        System.out.println(pageable.getSort());


        List<User> userList = new ArrayList<>();
        userList.add(new User());
        userList.add(new User());
        userList.add(new User());
        return userList;
    }


    //{id:\\d+}  表示只能是数字
    @GetMapping("/{id:\\d+}")
    @JsonView(User.UserDetailView.class)
    public User getInfo( @PathVariable String id) {
//    throw new RuntimeException("user not exist");
        System.out.println("进入getInfo服务");
        User user = new User();
        user.setUsername("tom");
        return user;
    }
}


@JsonSerialize


此注解用于属性或者getter方法上,用于在序列化时嵌入我们自定义的代码,比如序列化一个double时在其后面限制两位小数点。

因为在java中日期时期的时间戳是ms,我现在需要将ms转换为s,也就是除以1k

public class Date2LongSerializer extends JsonSerializer<Date> {

    @Override
    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        jsonGenerator.writeNumber(date.getTime() / 1000);
    }
}


使用:
private String id;

@MyConstraint(message = "这是一个校验测试")
private String username;

@NotBlank(message = "密码不能为空")
private String password;

@JsonSerialize(using = Date2LongSerializer.class)
@Past(message = "生日必须是过去的时间")
private Date birthday;

这样就完成了时间戳13位到10位的转换

@JsonIgnore、@JsonIgnoreProperties

@JsonIgnoreProperties:此注解是类注解,作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。@JsonIgnore:此注解用于属性或者方法上(最好是属性上),作用和上面的@JsonIgnoreProperties一样。
都是用于Json转换忽略空字段,也可以通过其它方式控制
第一种局部控制:



第二种:全局控制,我这用的springboot



还有其它json的相关注解,就不列举了,可以参考:https://www.cnblogs.com/guijl/p/3855329.html



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值