Spring的数据格式化和数据校验

一、数据格式化

Spring提供了注解的属性对象格式化功能:在Bean属性中设置、SpringMVC处理方法参数绑定数据、模型数据输出时自动通过注解应用格式化的功能。

在org.springframework.format.annotation包下面定义了两个格式化的注解类型:

1.DateTimeFormat

@DateTimeFormat注解可以对java.util.Date、java.util.Calendar等时间类型的属性进行标注。它支持以下几个互斥的属性:

      ·iso。类型为DateTimeFormat.ISO。以下是几个常用的可选值。

      DateTimeFormat.ISO.DATE:格式为yyyy-MM-dd。

      DateTimeFormat.ISO.DATE_TIME:格式为yyyy-MM-dd hh:mm:ss .SSSZ.

      DateTimeFormat.ISO.TIME:格式为hh:mm:ss.SSSZ。

      DateTimeFormat.ISO.NONE:表示不使用ISO格式的时间。

      ·pattern。类型为String,使用自定义的时间格式化字符串,如“yyyy-MM-dd hh:mm:ss”。

      ·style。类型为String,通过样式指定日期时间的格式,由两位字符组成,第1位表示日期的样式,第2位表示时间的格式,以下是几个常用的可选值。

      S:短日期/时间的样式

      M:中日期/时间的样式

      L:长日期/时间的样式

      F:完整日期/时间的样式

      -:忽略日期/时间的样式

2.NumberFormat

@NumberFormat可对类似数字类型的属性进行标注,它拥有两个互斥的属性。

      ~pattern。类型为String,使用自定义的数字格式化串,如“##,###。##”。

      ~style。类型为NumberFormat.Style,以下是几个常用的可选值:

      NumberFormat.CURRENCY: 货币类型

      NumberFormat.NUMBER:   正常数字类型

      NumberFormat.PERCEMT: 百分数类型

代码实例:

前端js页面:

<h3>数据格式化页面</h3>
    <form  action="test" method="post">
        <table>
            <tr>
                <td>日期类型:</td>
                <td><input type="text" id="birthday" name="birthday" /></td>
            </tr>
            <tr>
                <td>整数类型:</td>
                <td><input type="text" id="total" name="total" /></td>
            </tr>
            <tr>
                <td>百分数类型:</td>
                <td><input type="text" id="discount" name="discount" /></td>
            </tr>
            <tr>
                <td>货币类型:</td>
                <td><input type="text" id="money" name="money" /></td>
            </tr>
            <tr>
                <td><input id="submit" type="submit" value="提交" ></td>
            </tr>
        </table>

    </form>

实体接受:

public class User implements Serializable{

    //日期类型
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date birthday;

    //正常数字类型
    @NumberFormat(style = NumberFormat.Style.NUMBER,pattern = "#,###")
    private int total;

    //百分数类型
    @NumberFormat(style = NumberFormat.Style.PERCENT)
    private double discount;

    //货币类型
    @NumberFormat(style = NumberFormat.Style.CURRENCY)
    private double money;

    //省略get/set方法

}

说明:User类的多个属性使用了DateTimeFormat和NumberFormat注解,用于将页面传递的String转换成对应的格式化数据。

二、数据校验

1.分类:数据校验分为客户端校验和服务器端校验,客户端校验主要是过滤正常用户的误操作,通常在前端页面进行处理;服务器端校验是整个应用阻止非法数据的最后防线,只要是在后台进行处理。

2.为什么要做两个校验?

客户端校验的主要作用是防止正常用户的误输入,这仅能对输入进行初步的过滤;对于恶意用户的恶意行为,客户端校验将无能为力。所以,需要在客户端进行二次校验,客户端校验能把用户误输入的数据阻止在客户端,从而降低了服务器的负载。

3.两种校验的方法:一种是利用Spring自带的Validation校验框架;另一种是利用JSR303(java验证规范)实现校验功能。

4.Spring的Validation校验框架

      Spring的校验框架在org.springframework.validation包中,其中重要的接口和类如下:

      ~Validator。最重要的接口。该接口有两个方法:

        boolean supports(Class<?> clazz):该校验器能够对clazz类型的对象进行校验。

        void validate(Object target,Errors errors):对目标类target进行校验,并将校验错误记录在errors当中。

      ~Errors。Spring用来存放错误信息的接口。SpringMVC框架在将请求数据绑定到入参对象后,就会调用校验框架实施校验,而校验结果保存在处理方法的入参对象之后的参数对象当中。这歌保存校验结果的参数对象必须是Errors或者BindingResult类型。

      ~ValidationUtils。Spring提供的一个关于校验的工具类。它提供了多个给Errors对象保存错误的方法。

      ~LocalValidatorFactoryBean。位于org.springframework.validation.beanvalidation包中,给类即实现了Spring的Validator接口,也实现了JSR303的Validator接口。只要在Spring容器中定义一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的Bean中。定义一个LocalValidatorFactoryBean的Bean

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

在实际项目配置中<mvc:annotation-driven />已经默认配置好了一个LocalValidatorFactoryBean。

测试代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>测试validator</title>
</head>
<body>

   <h3>登录页面</h3>
    <form:form modelAttribute="user" action="login" method="post" >
        <table>
            <tr>
                <td><label>登录名</label> </td>
                <td><form:input path="loginname"/></td>
                <!--显示错误信息-->
                <td><form:errors path="loginname" cssStyle="color:red"/></td>
            </tr>
            <tr>
                <td><label>密码:</label> </td>
                <td><form:input path="password"/> </td>
                <td><form:errors path="password" cssStyle="color:red" /></td>
            </tr>
            <tr>
                <td><input type="submit" value="提交"/></td>
            </tr>
        </table>

    </form:form>
</body>
</html>

实体代码

public class User implements Serializable {

    private String loginname;

    private String password;

    //省略get/set方法
}

UserValidator代码实例:

package com.hu.controller;

import com.hu.model.User;
import org.springframework.stereotype.Repository;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

@Repository("userValidator")
public class UserValidator implements Validator {

    //该校验器能够对clazz类型的对象进行校验
    @Override
    public boolean supports(Class<?> aClass) {
        return User.class.isAssignableFrom(aClass);
    }

    //对目标类target进行校验,并将校验错误记录在errors当中
    @Override
    public void validate(Object o, Errors errors) {
        /**
         * 使用ValidationUtils中的一个静态方法rejectIfEmpty()来对loginname属性进行校验,假如
         * loginname属性是null或者空字符串的话,就拒绝验证通过
         */
        ValidationUtils.rejectIfEmpty(errors,"loginname",null,"登录名不能为空");
        ValidationUtils.rejectIfEmpty(errors,"password",null,"密码不能为空");
        User user = (User)o;
        if (user.getLoginname().length() > 10) {
            errors.rejectValue("loginname",null,"y=用户名不能超过10个字符");
        }
        if (user.getPassword() !=null && !user.getPassword().equals("") && user.getPassword().length()<6) {
            errors.rejectValue("password",null,"密码不能小于6位");
        }
    }
}

controller代码实现:

package com.hu.controller;

import com.hu.converter.StringToDateConverter;
import com.hu.model.User;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.support.RequestContext;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

//Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
public class UserController {

    @Autowired
    @Qualifier("userValidator")
    private UserValidator userValidator;

    private static final Log logger = LogFactory.getLog(UserController.class);

    @RequestMapping(value = "/{formName}")
    public String loginForm(@PathVariable String formName,Model model) {
        User user = new User();
        model.addAttribute("user",user);
        return formName;
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(@ModelAttribute User user, Model model, Errors errors) {
        logger.info(user);
        model.addAttribute("user",user);
        userValidator.validate(user,errors);
        if (errors.hasErrors()) {
            return "loginForm";
        }
        return "success";
    }


}

5.JSR303校验。

JSR303是java为Bean数据合法性校验提供的一个标准规范,叫做Bean Validation。官方参考实现的是Hibernate Validator。就是提供注解的方法进行数据校验。

JSR303注解
注解 功能 范例
@Null 验证对象是否为null

@Null

String name;

@NotNull 验证对象是否不为null,无法检查长度为0的字符串,用于验证基本数据类型

@NotNull

String name;

@AssertTrue 验证boolean对象是否为true

@AssertTrue

boolean isEmpty;

@AssertFalse 验证boolean对象是否为false

@AssertFalse

boolean isEmpty;

@Max(value) 验证Number和String对象是否小于等于指定的值

@Max(18)

Int age;

@Min(value) 验证Number和String对象是否大于等于指定的值

@Min(1)

Int age;

@DecimalMax(value) 被标注的值必须不大于约束中指定的最大值。这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示,小数存在精度

@DecimalMax(1.1)

BigDecimal price;

@DecimalMin(value) 被标注的值必须不小于约束中指定的最小值。这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示,小数存在精度

@DecimalMin(1.1)

BigDecimal price;

@Digits(integer,fraction) 验证字符串是否是符合指定格式的数字,integer指定整数精度,fraction指定小数精度

@Digits(integer=2,fraction=2)

BigDecimal price;

@Size(min,max) 验证对象(Array、Collection、Map、String)长度是否在给定的范围之内

@Size(min=10,max20)

String name;

@Past 验证Date和Calendar对象是否在当前时间之前

@Past

Date birthday

@Future 验证Date和Calendar对象是否在当前时间之后

@Future

Date birthday

@Pattern 验证String对象是否符合正则表达式的规则

@Pattern(regexp="[0-9]{1,8}")

String text;

HibernateValidator扩展的注解
注解 功能 范例
@NotBlank 检查约束字符串是不是Null,被Trim的长度是否大于0.只对字符串,且会去掉前后空格

@NotBlank

String name;

@URL 验证是否是合法的url

@URL

String url

@Email 验证是否是合法的邮箱地址

@Email

Stirng email;

@CreditCardNumber 验证是否是合法的信用卡号码

@CreditCardNumber

String card;

@Length(min,max) 验证字符串的长度必须在指定的范围内

@Length(min=1,max=8)

String password;

@NotEmpty 检查元素是否为null或者empty。用于Array、Collection、Map、String

@NotEmpty

String name;

@Range(min,max,message) 验证属性值必须在合适的范围内 @Range(min=0,max=18,message="未成年人年龄小于18岁")

猜你喜欢

转载自blog.csdn.net/huxiaodong1994/article/details/81545091