1. 程式人生 > >springmvc_引數校驗自定義註解

springmvc_引數校驗自定義註解

呼叫的例子

@PostMapping("/create")
public void create(@RequestBody @Valid ProductSerCreateInput productSerCreateInput, Errors errors) {
   ApiException.maybeThrowValidationError(errors);
}

其中ApiException為

package com.cmiinv.shp.util.api;

import lombok.Getter;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;

import java.util.stream.Collectors;

/**
 * @author LiuQi
 */
public class ApiException extends RuntimeException implements MessageSourceResolvable {

	@Getter
	private String[] codes;

	@Getter
	private Object[] arguments;

	@Override
	public String getDefaultMessage() {
		if (getMessage() != null) {
			return getMessage();
		} else if (getCause() != null) {
			return getCause().getMessage();
		} else {
			return null;
		}
	}

	public ApiException(String code, Object... arguments) {
		this(code, arguments, null, null);
	}

	public ApiException(String code, Object[] arguments, String message) {
		this(code, arguments, message, null);
	}

	public ApiException(String code, Object[] arguments, Throwable cause) {
		this(code, arguments, null, cause);
	}

	public ApiException(String code, Object[] arguments, String message, Throwable cause) {
		super(message, cause);
		this.codes = new String[]{code};
		this.arguments = arguments;
	}

	public String getCode() {
		return codes[0];
	}

	public static void maybeThrowValidationError(Errors errors) {
		if (errors != null && errors.hasErrors()) {
			String message = errors.getAllErrors().stream()
					.filter(objectError -> objectError instanceof FieldError)
					.map(objectError -> {
						FieldError fieldError = (FieldError) objectError;
						return "{" + fieldError.getField() + "}" + fieldError.getDefaultMessage();
					})
					.collect(Collectors.joining(";"));
			throw new ApiException(ErrorCodes.INVALID_INPUT, null, message);
		}
	}

	public static ApiException propagate(String errorCode, Object... arguments) {
		return new ApiException(errorCode, arguments);
	}

}

javax.validation.Valid

@Valid啟用實體類中的自定義註解,BindingResult 用來返回錯誤資訊

//import org.springframework.validation.BindingResult;
//import org.springframework.validation.Errors;
public Xxxx login(@Valid xxxModel , BindingResult bindingResult){
    if(bindingResult.hasErrors()){//返回具體的錯誤資訊
      System.out.println("message="+bindingResult.getFieldError().getDefaultMessage());  //返回的具體資訊
    }
}
public Xxxx login(@Valid xxxModel , Errors errors
){ if(errors != null && errors.hasErrors()){   String message = errors.getAllErrors().stream()     .filter(objectError -> objectError instanceof FieldError)     .map(objectError -> {         FieldError fieldError = (FieldError) objectError;         return "{" + fieldError.getField() + "}" + fieldError.getDefaultMessage();         })     .collect(Collectors.joining(";"));   System.out.println("message="+message); } } 常用的自定義註解 @NotEmpty(message = "password 為空") //javax.validation.constraints.NotEmpty; @Min //不能低於某個值 @AssertFalse //該欄位為false時才能驗證通過 @AssertTrue //該欄位為true時才能驗證通過 @DecimalMax //驗證小數的最大值@DecimalMax(value = "12.35") @DecimalMin //驗證小數的最小值 @Digits(integer = 2, fraction = 2) //驗證數字的整數位和小數位的位數是否超過指定的長度 private double money; ---日期--- @Future //必須在當前日期之後 private Date date; @Past //必須在當前日期之前 private Date date ; @Pattern(regexp = "[abc]") //與給定的正則相配製

自己實現自定義校驗註解 

自定義的註解裡必須有這幾樣要素
a.  String message() default "";
b.  public Class<?>[] groups() default {};
c.  Class<? extends Payload>[] payload() default {};
@Constraint(validatedBy = Xxxx.class)  指定具體的約束類(也可以為內部類) 用來實現自定義的校驗規則

import javax.validation.ConstraintValidator;

import com.qbsea.mysboot2common.modlues.app.service.AppService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;


@Target({FIELD,METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {MqbStringChecker.IsMobileValidator.class})
@Inherited
@Documented
public @interface MqbStringChecker {
    String message() default "手機號不正確";
    public Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    @Service
    class IsMobileValidator implements ConstraintValidator<MqbStringChecker,String> {
        @Autowired
        AppService appService;

        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            System.out.println(appService.findBy().get());
            if(value.startsWith("150")){//測試不能能150開頭的手機號
                return false;
            }
            return true;
        }
    }
}