validation-api之hibernate-validator的使用


JSR規范

JSR是Java Specification Requests的縮寫,意思是Java規范提案。是指向JCP(Java Community Process,JCP維護的規范包括J2ME、J2SE、J2EE,XML,OSS,JAIN等)提出新增一個標准化技術規范的正式請求。任何人都可以提交JSR,以向Java平台增添新的API和服務。JSR已成為Java界的一個重要標准。
JSR規范,JDBC、EJB、NIO、JDBC、JSP、JMX等都是JSR規范中的。

validation-api和hibernate-validator

validation-api只是一套標准,是Java EE6中的一項子規范,JSR規范編號303,叫做BeanValidation,官方參考實現是hibernate-validator。后來又擴展了JSR 349,提出了依賴注入、注解等內容。

hibernate-validator java代碼

maven坐標

hibernate-validator中包含了validation-api,所以不用重復引入。

    <!--注解實現校驗-->
    <dependency>
      <groupId>javax.el</groupId>
      <artifactId>javax.el-api</artifactId>
      <version>2.2.4</version>
    </dependency>
    <!--  hibernate-validator-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.2.2.Final</version>
    </dependency>

實體類

package com.validation;

import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

@Data
public class Student implements Serializable {

    @NotNull(message = "名字不能為空")
    private String name;

    @Size(min = 6,max = 30,message = "地址應該在6-30字符之間")
    private String address;

    @DecimalMax(value = "100.00",message = "體重有些超標哦")
    @DecimalMin(value = "60.00",message = "多吃點飯吧")
    private BigDecimal weight;

    private String friendName;

    @AssertTrue
    private Boolean isHaveFriend(){
        return friendName != null?true:false;
    }

    @Future(message = "生日必須在當前時間之前")
    private Date birthday;

    @Pattern(regexp = "^(.+)@(.+)$",message = "郵箱的格式不合法")
    private String email;
}

測試類

package com.validation;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

public class StudentTest implements Serializable {
    //獲取驗證器工廠
    private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

    public static void main(String[] args) {
        Student bean = new Student();
        bean.setName(null);
        bean.setAddress("揚州");
        bean.setBirthday(new Date());
        bean.setFriendName(null);
        bean.setWeight(new BigDecimal(30));
        bean.setEmail("163.com");
        //驗證實體數據
        List<String> validate = validate(bean);
        validate.forEach(row -> {
            System.out.println(row.toString());
        });
    }

    /**
     * 驗證實體
     * @param t 實體類
     * @return 返回實體類的驗證message集合
     */
    public static <T> List<String> validate(T t) {
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
        List<String> messageList = new ArrayList<>();
        for (ConstraintViolation<T> constraintViolation : constraintViolations) {
            messageList.add(constraintViolation.getMessage());
        }
        return messageList;
    }
}

測試結果
image

Spring MVC集成hibernate-validator

maven坐標

jsr-349,hibernate-validator中包含了validation-api 1.1.0這個接口包,所以不用重復引入。

    <!--注解實現校驗,spring mvc可以不引用,但是為了junit使用依然引用-->
    <dependency>
      <groupId>javax.el</groupId>
      <artifactId>javax.el-api</artifactId>
      <version>2.2.4</version>
    </dependency>
    <!--  hibernate-validator-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.2.2.Final</version>
    </dependency>

spring-mvc.xml

HibernateValidator沒有使用國際化,配置如下

    <!-- HibernateValidator -->
    <mvc:annotation-driven validator="validator"/>
    <!-- 以下 validator  ConversionService 在使用 mvc:annotation-driven 會 自動注冊-->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
    </bean>

model類

使用javax.validation的@NotNull、@Pattern、@Size和hibernate.validator的@NotEmpty、@Length等注解,注解中可以用message屬性自定義提示。

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@Data
@TableName(value = "t_admin")
public class TAdmin implements Serializable {

    @TableId(value = "id", type = IdType.AUTO)
    @NotNull(message = "主鍵不能為null")
    private Integer id;

    @TableField(value = "name")
    @NotEmpty
    @Length(min = 5, max = 20)
    @Pattern(regexp = "[a-zA-Z]{5,20}",message = "只能為5到20位的英文字母")
    private String name;

    @TableField(value = "username")
    @NotEmpty
    @Size(min = 5, max = 20)
    private String username;

    @TableField(value = "password")
    @NotNull
    private String password;
}

Controller層

@Valid或者@Validated注解驗證。

    @RequestMapping("/save")
    @ResponseBody
    public Object save(@Valid TAdmin user, BindingResult bindingResult) {
        Map<String, Object> result = new HashMap<String, Object>();
        /*獲取BeanValid驗證消息*/
        if(bindingResult.hasErrors()) {  //如果有驗證出錯誤
            if(bindingResult.hasErrors()) {
                //獲取所有錯誤
                List<FieldError> errs = bindingResult.getFieldErrors();
                //把所有所處的field和defaultmessage拿出來放入Map中
                Map<String, String> mapErrors = new LinkedHashMap<String, String>();
                for(FieldError err : errs) {
                    mapErrors.put(err.getField(), err.getDefaultMessage());
                }
                result.put("success", false);
                result.put("errors", mapErrors);
                return result;
            }
        }

        boolean r = adminService.save(user);
        result.put("success", true);
        result.put("result", r);
        return result;
    }

測試結果

image
參考:
https://www.cnblogs.com/softidea/p/10072114.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM