SpringMVC-数据验证

数据验证(数据验证错误不会报异常)

和类型转化不一样
     类型转换:form表单提交的是字符串, 但是springMVC接收的userId是Integer  如果表单填写的是aa  aa转化为Integer的时候就会报异常出现类型转化错误
     数据验证:form表单的类型填写的是正确的, 比如年龄要求填写5-10岁的  就需要进行数据的验证是否符合自己定义的


@Null 必须为 null
@NotNull 必须不为 null
@AssertTrue 必须为 true
@AssertFalse 必须为 false
@Min(value) 必须大于或等于 value
@Max(value) 必须小于或等于 value
@DecimalMin(value) 必须大于或等于 value
@DecimalMax(value) 必须小于或等于 value
@Size(max,min) 大小必须在 max min 限定的范围内
@Digits(integer,fratction) 值必须是一个数字,且必须在可接受的范围内
@Past 只能用于日期型,且必须是过去的日期
@Future 只能用于日期型,且必须是将来的日期
@Pattern(value) 必须符合指定的正则表达式
@Email                                                                       必须是格式正确的 Email 地址
@Length 被注释的字符串大小必须在指定的范围内
@NotEmpty 被注释的字符串不能是空字符串
@Range 被注释的元素必须在指定的范围内

数据验证的步骤

1.在当前工程类路径下加入以下jar包

classmate-0.8.0.jar
hibernate-validator-5.0.0.CR2.jar
hibernate-validator-annotation-processor-5.0.0.CR2.jar
jboss-logging-3.1.1.GA.jar
validation-api-1.1.0.CR1.jar

2.在Tomcatlib目录下加入以下jar包

javax.el-2.2.4.jar
javax.el-api-2.2.4.jar
el-api-2.2.jar

3.在需要 user 验证的字段上添加验证注解

@Length(min=5,max=10)  //字符串长度在5~10之间
@NotEmpty     //非空;空串也不可以
private String userName;
    
//20~30之间
@Min(value=20)
@Max(value=30)
private int age ;
    
@Email    
private String email;
    
@Past    //必须是一个过去的时间
@DateTimeFormat(pattern= "yyyy-MM-dd")   //此处是类型转换 不是数据验证  可由 pattern= "yyyy-MM-dd" 这个参数确定是类型转换
private Date birthday; 
    
@Size(min=3, max=5)  //长度在3~5之间
@NotNull             //非空
private List<String> multiValues;

4.目标方法的bean前添加@Validated注解

方法1:

※注意:在@Validated注解修饰的bean之后, 紧跟Errors(或BindingResult)类型的参数。
在@Validated注解修饰的bean和Errors参数之间不能再有其他的参数!
    正确:public String saveUser(@Validated User user, BindingResult bindingResult) { }
    错误:public String saveUser(@Validated User user, String xxx, BindingResult bindingResult) {}


//调用Errors的方法在目标方法中检验是否没有通过验
 public String saveUser(@Validated User user, BindingResult bindingResult) {
 
      //如果不进行BindingResult bindingResult判断不会抛异常,应当进行判断,出现错误后返回表单页面,进行错误提示
      if (result.hasErrors()) {
           //数据绑定错误,做处理
            1)可以跳转到元表单页面进行错误消息的显示,这是需要用到spring的form表单以及国际化定制错误消息即步骤6 7
            2)抛出自定义的异常(推荐使用)
      }

} 
方法2:
//或者是目标方法的bean前不加@Validated注解  
//用以下方法验证 在bigpay gateway的快捷支付controller可以看到
 @Size(max = 8, message = "产品类型[productType]长度最大8位")
 @NotBlank(message = "产品类型[productType]不能为空")
 private String productType;

 @Size(max = 32, message = "支付Key[payKey]长度最大32位")
 @NotBlank(message = "支付Key[payKey]不能为空")
 private String payKey;  

// 参数校验
public void initPay(QuickPayApplyVo quickPayApplyVo, BindingResult bindingResult, HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest) throws IOException {
    
    validator.validate(quickPayApplyVo, bindingResult);
    if (bindingResult.hasErrors()) {
        String errorResponse = quickPayService.getErrorResponse(bindingResult);
        LOG.info("请求参数异常:{}", errorResponse);
        stringObjectMap = new HashMap<String, Object>();
        stringObjectMap.put("resultCode", ReturnCodeEnum.REQUEST_PARAMETER_ERROR.getCode());
        stringObjectMap.put("orderStatus", "");
        stringObjectMap.put("retMsg", errorResponse);
     }
}
方法3:
//或者以下验证方法:在payCenter service中可以看到
@Autowired
private Validator validator;

// 1.校验参数
try {
     BeanValidators.validateWithException(validator, reqModel);
} catch (RuntimeException e) {
     throw new ResponseErrorException("参数校验失败:" + e.getMessage());
}


//要验证的类
public class OnlinePayRequestNew extends BaseRequest {

    private static final long serialVersionUID = -3390992083050409730L;

    @NotBlank(message = "order_no必填")
    private String order_no;
   
    private int third_pay_platform;
    private int pay_channel;
    @Min(value = 1, message = "pay_money金额非法")
    private int pay_money;
   
    @NotBlank(message = "BankCode必填,格式诸如CCB-2C或CCB-2C-C")
    private String bank_code;
    @NotBlank(message = "notify_url必填")
    private String notify_url;
    @NotBlank(message = "return_url必填")
    private String return_url;

    private String merchant_id;
    
    private String order_time;
    @NotBlank(message = "goods_name必填")
    private String goods_name;
   
    private int time_expire_minutes;
  
    private String remark;		
}


/**
 * JSR303 Validator(Hibernate Validator)工具类.
 * 
 * ConstraintViolation中包含propertyPath, message 和invalidValue等信息.
 * 提供了各种convert方法,适合不同的i18n需求:
 * 1. List<String>, String内容为message
 * 2. List<String>, String内容为propertyPath + separator + message
 * 3. Map<propertyPath, message>
 * 
 * 详情见wiki: https://github.com/springside/springside4/wiki/HibernateValidator
 * @author calvin
 * @version 2013-01-15
 */
public class BeanValidators {

	/**
	 * 调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException.
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void validateWithException(Validator validator, Object object, Class<?>... groups)
			throws ConstraintViolationException {
		Set<ConstraintViolation<Object>>  constraintViolations = validator.validate(object, groups);
		if (!constraintViolations.isEmpty()) {
			StringBuffer sb=new StringBuffer();
			for (ConstraintViolation constraintViolation : constraintViolations) {
				sb.append(constraintViolation.getMessage());
			}
			throw new RuntimeException(sb.toString());
		}

	}

	/**
	 * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>中为List<message>.
	 */
	public static List<String> extractMessage(ConstraintViolationException e) {
		return extractMessage(e.getConstraintViolations());
	}

	/**
	 * 辅助方法, 转换Set<ConstraintViolation>为List<message>
	 */
	@SuppressWarnings("rawtypes")
	public static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {
		List<String> errorMessages = Lists.newArrayList();
		for (ConstraintViolation violation : constraintViolations) {
			errorMessages.add(violation.getMessage());
		}
		return errorMessages;
	}

	/**
	 * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property, message>.
	 */
	public static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {
		return extractPropertyAndMessage(e.getConstraintViolations());
	}

	/**
	 * 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>.
	 */
	@SuppressWarnings("rawtypes")
	public static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) {
		Map<String, String> errorMessages = Maps.newHashMap();
		for (ConstraintViolation violation : constraintViolations) {
			errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
		}
		return errorMessages;
	}

	/**
	 * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath message>.
	 */
	public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) {
		return extractPropertyAndMessageAsList(e.getConstraintViolations(), " ");
	}

	/**
	 * 辅助方法, 转换Set<ConstraintViolations>为List<propertyPath message>.
	 */
	@SuppressWarnings("rawtypes")
	public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) {
		return extractPropertyAndMessageAsList(constraintViolations, " ");
	}

	/**
	 * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath +separator+ message>.
	 */
	public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {
		return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator);
	}

	/**
	 * 辅助方法, 转换Set<ConstraintViolation>为List<propertyPath +separator+ message>.
	 */
	@SuppressWarnings("rawtypes")
	public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations,
			String separator) {
		List<String> errorMessages = Lists.newArrayList();
		for (ConstraintViolation violation : constraintViolations) {
			errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage());
		}
		return errorMessages;
	}
}

猜你喜欢

转载自blog.csdn.net/wxd_1024/article/details/80087005