自定義校驗注解(org.hibernate.validator)


如何簡單實現一個自定義校驗注解。

validator實現了java的校驗器API,里面提供了很多校驗器注解,但是有時候這些注解不能滿足我們的業務校驗。
validator也提供了自定義注解的接口,我們只要繼承這個接口,並且實現它的方法,就能完成一個簡單的自定義注解

注解類

package com.custom;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
//這個注解能使用在哪里
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
//這個注解什么時候執行 @Retention(RUNTIME)
//這個注解對應的校驗器類,(這個類一般實現了校驗器接口) @Constraint(validatedBy
= { ParamNotNullValidator2.class }) public @interface ParamNotNull2 {
  //異常消息 String message()
default "參數不能為空----自定義注解";   //剩下的自己按需要加 Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; }

校驗器類

package com.custom;

import com.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
//第一個參數指定注解類,第二個指定校驗值類型
public class ParamNotNullValidator2 implements ConstraintValidator<ParamNotNull2,String> {
    @Autowired
    private DeptService deptService;
  //校驗方法,里面寫自己需要校驗的邏輯
public boolean isValid(String value, ConstraintValidatorContext context) {
     //先判斷這個值是否為null和""
if( value == null || value.equals("") ){ return false; }     //調用業務類方法 String name = deptService.queryOne(value); if(name == null){ return true; }else { return false; } } }

控制器類

package com.controller;

import com.entity.Dept;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.validation.Valid;

@Controller
public class TestDeptController {
  //使用@Valid聲明使用校驗器
    @RequestMapping("/queryOne")
    public String queryOne(@Valid Dept dept, BindingResult bindingResult, Model model){
        if(bindingResult.hasErrors()){
            model.addAttribute("msg",bindingResult.getFieldError("name"));
        }else {
            model.addAttribute("msg","這個名字可以用");
        }
        return "index";
    }
}

實體類

package com.entity;

import com.custom.ParamNotNull2;

public class Dept {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    @ParamNotNull2
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

 

主頁面JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <form action="/queryOne" method="post">
        <input type="text" name="name"/>
        <input type="submit" value="提交"/>
    </form>
</body>

</html>

成功或者失敗跳轉JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>${msg}</h1>
</body>
</html>

這樣我們就實現了一個基於Spring Mvc的自定義校驗器

說一說常見的異常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

這個異常:說明你寫的自定義控制器里面的isValid方法里面執行出現了異常,常見的錯誤:用戶界面使用form表單提交,那么控制器方法的value參數,當用戶沒有傳參的時候,是一個null對象,如果使用
equals判斷這個value是否為"",會出現這個異常,下面還有一條異常提示NullPointerException,這說明這個value沒有值時會給個null對象,使用equals是會出現異常的,因為它是在校驗器方法執行的
所以會報上面的異常,解決辦法,去掉equals("")判斷,換成==null,或者讓equals在后面判斷

如果不使用form表單提交的數據,如果用戶沒有傳值的情況下,不會給null對象給value,會給一個"",說明:get請求方法是通過Url傳值,所以會給一個"",post請求會給一個null對象,至於方法里面的邏輯如何判斷
,各位就見仁見智了。


免責聲明!

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



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