欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringMVC Validator驗(yàn)證示例

 更新時(shí)間:2017年01月12日 10:49:31   作者:茶飲月  
SpringMVC服務(wù)器驗(yàn)證一種是有兩種方式,一種是基于Validator接口,一種是使用Annotaion JSR-303標(biāo)準(zhǔn)的驗(yàn)證,本篇文章主要介紹,有興趣的可以了解一下。

SpringMVC服務(wù)器驗(yàn)證一種是有兩種方式,一種是基于Validator接口,一種是使用Annotaion JSR-303標(biāo)準(zhǔn)的驗(yàn)證,下面主要是學(xué)習(xí)這兩種,工作中推薦后者,方便很多

一.基于Validator接口的驗(yàn)證.

首先創(chuàng)建User實(shí)例,并加入幾個(gè)屬性

public class User {
  private String username;
  private String password;
  private String nickname;

  public String getUsername() {
    return username;
  }

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

  public String getPassword() {
    return password;
  }

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

  public String getNickname() {
    return nickname;
  }

  public void setNickname(String nickname) {
    this.nickname = nickname;
  }

  @Override
  public String toString() {
    return "username--"+username+"password--"+password+"nickname--"+nickname;
  }
}

接著創(chuàng)建用于校檢的類UserValidator,讓其實(shí)現(xiàn)Validator,覆蓋其中的兩個(gè)方法

import main.java.model.User;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class UserValidator implements Validator {


  @Override
  public boolean supports(Class<?> aClass) {
    //判斷是否是要校驗(yàn)的類,這里是User
    return User.class.equals(aClass);
  }

  @Override
  public void validate(Object o, Errors errors) {
    User u = (User) o;
    if (null == u.getPassword() || "".equals(u.getPassword())){
      //此方法可以加四個(gè)參數(shù),第一個(gè)表單域field,
      //區(qū)分是哪個(gè)表單出錯(cuò),第二個(gè)errorCode錯(cuò)誤碼,
      //第三個(gè)制定了資源文件中占位符,第四個(gè)具體錯(cuò)誤返回信息
      //簡(jiǎn)寫版可以把2,3參數(shù)去掉
      errors.rejectValue("password",null,null,"password is null");
    }
  }
}

上面的類只實(shí)現(xiàn)了對(duì)密碼判斷是否為空,為空則注冊(cè)這一錯(cuò)誤信息,也就是”password is null”,接下來(lái)要實(shí)現(xiàn)控制器,控制器要做的事情,第一是注冊(cè)這個(gè)校驗(yàn)器,第二是實(shí)現(xiàn)校驗(yàn).

import main.java.model.User;
......

/**
 * 加上@Controller決定這個(gè)類是一個(gè)控制器
 */
@Controller
@RequestMapping("/user")
public class HelloController {

  //我們知道在Controller類中通過(guò)@InitBinder標(biāo)記的方法只有在請(qǐng)求當(dāng)前Controller的時(shí)候才會(huì)被執(zhí)行
  //所以在這里注冊(cè)校驗(yàn)器
  @InitBinder
  public void initBainder(DataBinder binder){
    binder.replaceValidators(new UserValidator());

  }
  //這個(gè)方法主要是跳轉(zhuǎn)到登錄頁(yè)面
  @RequestMapping(value = "/login",method = RequestMethod.GET)
  public String login(Model model){
    model.addAttribute(new User());
    return "user/login";
  }
  //處理登錄表單
  @RequestMapping(value = "/login",method = RequestMethod.POST)
  public String login(@Validated User user, BindingResult br){

    if (br.hasErrors()){
      return "user/login";
    }
    return "--";
  }
  }

上面代碼可以看到@Validated User user, BindingResult br這兩個(gè)參數(shù),@Validated表明參數(shù)user是要校驗(yàn)的類,BindingResult是存儲(chǔ)錯(cuò)誤信息的類,兩者必須一一對(duì)應(yīng),并且位置挨著,不能中間有其他參數(shù),

最后隨便寫一個(gè)jsp頁(yè)面實(shí)現(xiàn)校檢

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%
  request.setCharacterEncoding("utf-8");
%>
<html>
<head>
  <meta charset="utf-8">
  <title>用戶登錄</title>
</head>
<body>
  <sf:form modelAttribute="user" method="post">
    用戶名:<sf:input path="username"/><sf:errors path="username"/>
    <br>
    密碼:<sf:input path="password"/><sf:errors path="password"/>
    <br>
    昵稱:<sf:input path="nickname"/><sf:errors path="nickname"/>
    <br>
    <input type="submit" value="提交">
  </sf:form>
</body>
</html>

這里寫圖片描述

前面實(shí)現(xiàn)的是局部校驗(yàn),只對(duì)當(dāng)前控制器有效,如果要實(shí)現(xiàn)全局校驗(yàn)的話需要配置springMVC.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

  <mvc:annotation-driven validator="userValidator"/>

  <bean id="userValidator" class="com.xxx.xxx.UserValidator"/>

  ...
</beans>

二.使用Annotaion JSR-303標(biāo)準(zhǔn)的驗(yàn)證

使用這個(gè)需要導(dǎo)入支持JSR-303標(biāo)準(zhǔn)的包,建議使用hibernate Validator這個(gè)包,先看這個(gè)標(biāo)準(zhǔn)的原生標(biāo)注


限制 說(shuō)明
@Null 限制只能為null
@NotNull 限制必須不為null
@AssertFalse 限制必須為false
@AssertTrue 限制必須為true
@DecimalMax(value) 限制必須為一個(gè)不大于指定值的數(shù)字
@DecimalMin(value) 限制必須為一個(gè)不小于指定值的數(shù)字
@Digits(integer,fraction) 限制必須為一個(gè)小數(shù),且整數(shù)部分的位數(shù)不能超過(guò)integer,小數(shù)部分的位數(shù)不能超過(guò)fraction
@Future 限制必須是一個(gè)將來(lái)的日期
@Max(value) 限制必須為一個(gè)不大于指定值的數(shù)字
@Min(value) 限制必須為一個(gè)不小于指定值的數(shù)字
@Past 限制必須是一個(gè)過(guò)去的日期
@Pattern(value) 限制必須符合指定的正則表達(dá)式
@Size(max,min) 限制字符長(zhǎng)度必須在min到max之間
@Past 驗(yàn)證注解的元素值(日期類型)比當(dāng)前時(shí)間早
@NotEmpty 驗(yàn)證注解的元素值不為null且不為空(字符串長(zhǎng)度不為0、集合大小不為0)
@NotBlank 驗(yàn)證注解的元素值不為空(不為null、去除首位空格后長(zhǎng)度為0),不同于@NotEmpty,@NotBlank只應(yīng)用于字符串且在比較時(shí)會(huì)去除字符串的空格
@Email 驗(yàn)證注解的元素值是Email,也可以通過(guò)正則表達(dá)式和flag指定自定義的email格式

要使用很簡(jiǎn)單,在需要驗(yàn)證的變量前面加上該Annotation即可,看下面使用后的User

public class User {
  @NotEmpty(message = "用戶名不能為空")
  private String username;
  @Size(min=6 ,max= 20 ,message = "密碼長(zhǎng)度不符合標(biāo)準(zhǔn)")
  private String password;
  private String nickname;

  ......
}

然后再控制器里面加入驗(yàn)證就可以了

@Controller
@RequestMapping("/user")
public class HelloController {


  @RequestMapping(value = "/login",method = RequestMethod.GET)
  public String login(Model model){
    model.addAttribute(new User());
    return "user/login";
  }

  @RequestMapping(value = "/login",method = RequestMethod.POST)
  public String login(@Validated User user, BindingResult br){

    if (br.hasErrors()){
      return "user/login";
    }
    return "user/login";
  }
  }

然后jsp頁(yè)面還是之前的頁(yè)面,驗(yàn)證效果如下,這種方法明顯簡(jiǎn)單多了

這里寫圖片描述

3.定義自己的Annotation Validator

這部分直接從[大牛][1]那拷貝過(guò)來(lái)的.

除了JSR-303原生支持的限制類型之外我們還可以定義自己的限制類型。定義自己的限制類型首先我們得定義一個(gè)該種限制類型的注解,而且該注解需要使用@Constraint標(biāo)注?,F(xiàn)在假設(shè)我們需要定義一個(gè)表示金額的限制類型,那么我們可以這樣定義:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

import com.xxx.xxx.constraint.impl.MoneyValidator;

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MoneyValidator.class)
public @interface Money {

  String message() default"不是金額形式";

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

  Class<? extends Payload>[] payload() default {};

}

我們可以看到在上面代碼中我們定義了一個(gè)Money注解,而且該注解上標(biāo)注了@Constraint注解,使用@Constraint注解標(biāo)注表明我們定義了一個(gè)用于限制的注解。@Constraint注解的validatedBy屬性用于指定我們定義的當(dāng)前限制類型需要被哪個(gè)ConstraintValidator進(jìn)行校驗(yàn)。在上面代碼中我們指定了Money限制類型的校驗(yàn)類是MoneyValidator。另外需要注意的是我們?cè)诙x自己的限制類型的注解時(shí)有三個(gè)屬性是必須定義的,如上面代碼所示的message、groups和payload屬性。

在定義了限制類型Money之后,接下來(lái)就是定義我們的限制類型校驗(yàn)類MoneyValidator了。限制類型校驗(yàn)類必須實(shí)現(xiàn)接口javax.validation.ConstraintValidator,并實(shí)現(xiàn)它的initialize和isValid方法。我們先來(lái)看一下MoneyValidator的代碼示例:

import java.util.regex.Pattern;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.xxx.xxx.constraint.Money;

public class MoneyValidator implements ConstraintValidator<Money, Double> {

  private String moneyReg = "^\\d+(\\.\\d{1,2})?$";//表示金額的正則表達(dá)式
  private Pattern moneyPattern = Pattern.compile(moneyReg);

  public void initialize(Money money) {
    // TODO Auto-generated method stub

  }

  public boolean isValid(Double value, ConstraintValidatorContext arg1) {
    // TODO Auto-generated method stub
    if (value == null)
      return true;
    return moneyPattern.matcher(value.toString()).matches();
  }

}

從上面代碼中我們可以看到ConstraintValidator是使用了泛型的。它一共需要指定兩種類型,第一個(gè)類型是對(duì)應(yīng)的initialize方法的參數(shù)類型,第二個(gè)類型是對(duì)應(yīng)的isValid方法的第一個(gè)參數(shù)類型。從上面的兩個(gè)方法我們可以看出isValid方法是用于進(jìn)行校驗(yàn)的,有時(shí)候我們?cè)谛r?yàn)的過(guò)程中是需要取當(dāng)前的限制類型的屬性來(lái)進(jìn)行校驗(yàn)的,比如我們?cè)趯?duì)@Min限制類型進(jìn)行校驗(yàn)的時(shí)候我們是需要通過(guò)其value屬性獲取到當(dāng)前校驗(yàn)類型定義的最小值的,我們可以看到isValid方法無(wú)法獲取到當(dāng)前的限制類型Money。這個(gè)時(shí)候initialize方法的作用就出來(lái)了。

我們知道initialize方法是可以獲取到當(dāng)前的限制類型的,所以當(dāng)我們?cè)谛r?yàn)?zāi)撤N限制類型時(shí)需要獲取當(dāng)前限制類型的某種屬性的時(shí)候,我們可以給當(dāng)前的ConstraintValidator定義對(duì)應(yīng)的屬性,然后在initialize方法中給該屬性賦值,接下來(lái)我們就可以在isValid方法中使用其對(duì)應(yīng)的屬性了。針對(duì)于這種情況我們來(lái)看一個(gè)代碼示例,現(xiàn)在假設(shè)我要定義自己的@Min限制類型和對(duì)應(yīng)的MinValidator校驗(yàn)器,那么我可以如下定義:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MinValidator.class)
public @interface Min {

  int value() default 0;

  String message();

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

  Class<? extends Payload>[] payload() default {};
}
MinValidator校驗(yàn)器
public class MinValidator implements ConstraintValidator<Min, Integer> {

  private int minValue;

  public void initialize(Min min) {
    // TODO Auto-generated method stub
    //把Min限制類型的屬性value賦值給當(dāng)前ConstraintValidator的成員變量minValue
    minValue = min.value();
  }

  public boolean isValid(Integer value, ConstraintValidatorContext arg1) {
    // TODO Auto-generated method stub
    //在這里我們就可以通過(guò)當(dāng)前ConstraintValidator的成員變量minValue訪問(wèn)到當(dāng)前限制類型Min的value屬性了
    return value >= minValue;
  }

}

繼續(xù)來(lái)說(shuō)一下ConstraintValidator泛型的第二個(gè)類型,我們已經(jīng)知道它的第二個(gè)類型是對(duì)應(yīng)的isValid的方法的第一個(gè)參數(shù),從我給的參數(shù)名稱value來(lái)看也可以知道isValid方法的第一個(gè)參數(shù)正是對(duì)應(yīng)的當(dāng)前需要校驗(yàn)的數(shù)據(jù)的值,而它的類型也正是對(duì)應(yīng)的我們需要校驗(yàn)的數(shù)據(jù)的數(shù)據(jù)類型。這兩者的數(shù)據(jù)類型必須保持一致,否則spring會(huì)提示找不到對(duì)應(yīng)數(shù)據(jù)類型的ConstraintValidator。建立了自己的限制類型及其對(duì)應(yīng)的ConstraintValidator后,其用法跟標(biāo)準(zhǔn)的JSR-303限制類型是一樣的。以下就是使用了上述自己定義的JSR-303限制類型——Money限制和Min限制的一個(gè)實(shí)體類:

public class User {

  private int age;

  private Double salary;

  @Min(value=8, message="年齡不能小于8歲")
  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Money(message="標(biāo)準(zhǔn)的金額形式為xxx.xx")
  public Double getSalary() {
    return salary;
  }

  public void setSalary(Double salary) {
    this.salary = salary;
  }

}

4.配合ajax驗(yàn)證

最近寫的項(xiàng)目,感覺(jué)直接使用validator不太好用,主要是返回時(shí)會(huì)刷新整個(gè)頁(yè)面才會(huì)出來(lái)錯(cuò)誤信息,體驗(yàn)相當(dāng)不好,驗(yàn)證還是用ajax體驗(yàn)比較好,所以配合ajax

思路:驗(yàn)證還是使用springMVC來(lái)驗(yàn)證,只是這次發(fā)現(xiàn)錯(cuò)誤的話,把錯(cuò)誤取出,存放到一個(gè)map中,然后ajax返回,頁(yè)面根據(jù)ajax返回值來(lái)判斷,從而顯示不同的信息

主要代碼:

 if (br.hasErrors()){//判斷是否有錯(cuò)誤
       //對(duì)錯(cuò)誤集合進(jìn)行遍歷,有的話,直接放入map集合中
      br.getFieldErrors().forEach(p->{
        maps.put(p.getField(),p.getDefaultMessage());
      });
      return maps;
    }

這樣的話 maps里面存放的就是 錯(cuò)誤變量名,錯(cuò)誤信息,例如 username -‘用戶名不能為空'

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中JDK14的新特性之JFR,JMC和JFR事件流(推薦)

    Java中JDK14的新特性之JFR,JMC和JFR事件流(推薦)

    JFR是一個(gè)基于事件的低開(kāi)銷的分析引擎,具有高性能的后端,可以以二進(jìn)制格式編寫事件,而JMC是一個(gè)GUI工具,用于檢查JFR創(chuàng)建的數(shù)據(jù)文件。本文給大家介紹Java中JDK14的新特性之JFR,JMC和JFR事件流的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2020-05-05
  • java的反射用不好試試內(nèi)省?

    java的反射用不好試試內(nèi)省?

    使用內(nèi)省相對(duì)于直接使用反射更加安全可靠,Java的反射機(jī)制比較特殊,它不同于一般的編程方式,稍不小心就容易破壞類的封裝性。練的不好,就容易走火入魔。沒(méi)關(guān)系,很多時(shí)候我們還可以使用Java的內(nèi)省機(jī)制哦
    2021-07-07
  • 5種Java中數(shù)組的拷貝方法總結(jié)分享

    5種Java中數(shù)組的拷貝方法總結(jié)分享

    這篇文章主要介紹了5種Java中數(shù)組的拷貝方法總結(jié)分享,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • List集合中對(duì)數(shù)據(jù)實(shí)現(xiàn)多重規(guī)則進(jìn)行排序的案例

    List集合中對(duì)數(shù)據(jù)實(shí)現(xiàn)多重規(guī)則進(jìn)行排序的案例

    今天小編就為大家分享一篇關(guān)于List集合中對(duì)數(shù)據(jù)實(shí)現(xiàn)多重規(guī)則進(jìn)行排序的案例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • 關(guān)于idea2020.3升級(jí)lombok不能使用的問(wèn)題

    關(guān)于idea2020.3升級(jí)lombok不能使用的問(wèn)題

    這篇文章主要介紹了關(guān)于idea2020.3升級(jí)lombok不能使用的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • SpringBoot?使用?Sa-Token?完成注解鑒權(quán)功能(權(quán)限校驗(yàn))

    SpringBoot?使用?Sa-Token?完成注解鑒權(quán)功能(權(quán)限校驗(yàn))

    Sa-Token?是一個(gè)輕量級(jí)?java?權(quán)限認(rèn)證框架,主要解決登錄認(rèn)證、權(quán)限認(rèn)證、單點(diǎn)登錄、OAuth2、微服務(wù)網(wǎng)關(guān)鑒權(quán)?等一系列權(quán)限相關(guān)問(wèn)題,這篇文章主要介紹了SpringBoot使用Sa-Token完成注解鑒權(quán)功能,需要的朋友可以參考下
    2023-05-05
  • java 如何判斷是否可以ping通某個(gè)地址

    java 如何判斷是否可以ping通某個(gè)地址

    這篇文章主要介紹了java 如何判斷是否可以ping通某個(gè)地址,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot+MyBatis+Redis實(shí)現(xiàn)分布式緩存

    SpringBoot+MyBatis+Redis實(shí)現(xiàn)分布式緩存

    本文主要介紹了SpringBoot+MyBatis+Redis實(shí)現(xiàn)分布式緩存,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • Java 利用棧來(lái)反轉(zhuǎn)鏈表和排序的操作

    Java 利用棧來(lái)反轉(zhuǎn)鏈表和排序的操作

    這篇文章主要介紹了Java 利用棧來(lái)反轉(zhuǎn)鏈表和排序的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • java 中Comparable與Comparator詳解與比較

    java 中Comparable與Comparator詳解與比較

    這篇文章主要介紹了java 中Comparable與Comparator詳解與比較的相關(guān)資料,需要的朋友可以參考下
    2017-04-04

最新評(píng)論