1. 程式人生 > >基於SpringMVC+hibernate-validator實現實現動態簽名驗證

基於SpringMVC+hibernate-validator實現實現動態簽名驗證

首先我這個標題的意思先大家說說,我想要做的事情。
例如:我現在提供一個api給別人使用,然後api可能存在加簽、解籤、驗籤等過程,而且假設我不同的接入者使用了不同的簽名規則MD5或者RAS,並且針對不同的bean,加簽的欄位也不同。

問題1:如何選擇實現動態簽名驗證(不同的簽名規則)?
問題2:如何對不同的bean中需要加簽的欄位進行驗證?

帶著這兩個問題,接下來我把我的實踐過程給大家一步一步給分享出來,也希望大家在看這篇文章的過程有任何疑問歡迎留言。

第一步:搭建一個springMVC專案,至於如何搭建請參考我的springMVC專案搭建的文章,這裡我就不多說了。

第二步:引入hibernate-validator包。通過maven配置檔案直接引入

<dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-validator</artifactId>
     <version>5.1.3.Final</version>
</dependency>

第三步:在springMVC配置檔案中開啟我們的驗證類,配置以下程式碼就會對標識有@Valid註解的入參(bean)進行驗證。

spring-mvc.xml

 <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"
/>

controller類中的片段程式碼

    @RequestMapping("creanteUser")
       public @ResponseBody UserBean creanteUser(@RequestBody  @Valid UserBean userBean){
        return userBean;
    }

我這裡使用了三個註解,@RequestMapping中表示請求的url為creanteUser,@ResponseBody表示對返回的引數序列化json/xml格式, @RequestBody這個表示對請求的引數進行反序列化成UserBean 物件,@Valid表示對UserBean 物件進行驗證,具體的驗證看UserBean 類。如下:

public class UserBean {

    @NotEmpty(message="姓名不能為空")
    private String name;

    @Range(min=20,max=120,message="年齡在20到120歲之間")
    private int age;

    ...getter/setter...
}

第四步:寫一個全域性異常前面類如下:

@ControllerAdvice
@ResponseBody
public class ExceptionAdvice {

    private static Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Response handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        logger.error("引數驗證失敗", e);
        BindingResult result = e.getBindingResult();
        StringBuffer sb = new StringBuffer();
        for (ObjectError error : result.getAllErrors()) {
            String field = error.getCode();
            String code = error.getDefaultMessage();
            String message = String.format("%s:%s", field, code);
            sb.append(message);
        }
        return new Response().failure(sb.toString());

    }

}

這個類的作用主要是用來對丟擲來的異常進行匹配攔截,如果在這個切面了異常類中有定義則就會攔截,我這裡只做了一個對引數異常的捕獲至於其它的有興趣的朋友可以自己去了解,然後友好的返回到前端。只需要把這個類在spring中加入掃描即可。

spring-mvc.xml

<context:component-scan base-package="com.hhh.api.advice" />

Response類:

public class Response {

    private String message;
    private String code;
    private Object data;

    public Response failure(String msg){
        this.message = msg;
        this.code = "false";
        return this;
    }
    ...getter/setter...
}

好了這樣我們一個簡單的驗證就做好了。現在進行測試。開啟google瀏覽器的Advanced Rest Client Application外掛進行測試,測試結果如下。
failure

這裡寫圖片描述

success
這裡寫圖片描述

以上就是一個簡單的驗證功能,接下來開始進入主題,對當前驗證進行擴充套件實現問題1跟問題2中的需求。

第二部分:自定義驗證規則

這一部分主要講述關於hibernate-validator驗證外掛的一個擴充套件,自定義驗證規則。

第一步:自定義一個驗證註解類

/**
 * 驗簽註解
 *
 * @author he
 * @since 1.0.0
 */
@Documented
@Target({ElementType.METHOD, ElementType.PARAMETER,ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SignValidator.class)
public @interface Sign {

    String message() default "sign validation is fail";

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

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

    Class<? extends SignValidation> value() default DefaultSignValidation.class;
}

這一部分需要注意的就是 message,groups,payload這三個方法是在這個註解類中必須有的。value方法是自己選擇定義的這裡我傳入了一個預設值DefaultSignValidation類,這個是一個預設的驗籤類。內容如下:

/**
 * 簽名驗證管理器
 * 
 * @author he
 * @since 1.0.0
 */
public class DefaultSignValidation implements SignValidation {
    @Override
    public boolean validation(SignBean signBean) {

        //todo

        return false;
    }
}

這個類很簡單,實現了驗籤介面,然後有一個驗籤的方法實現。我這裡直接返回false。然後我們看看SignValidation 介面:

/**
 * 簽名驗證
 *
 * @author he
 * @since 1.0.0
 */
public interface SignValidation {

    /**
     * 驗證
     * @Description 對object物件的加簽欄位進行驗證
     * @param  signBean  驗證物件
     * @return boolean  結果 true or false
     * @author hejiahua
     * @date 2016-3-25
     */
    boolean validation(SignBean signBean);

}

這個介面有一個形參SignBean ,這個SignBean 是一個驗證實體,如下:

/**
 * 簽名物件
 *
 * @author he
 * @since 1.0.0
 */
@Sign(message="驗籤失敗",value = DefaultSignValidation.class)
public class SignBean {
    @NotEmpty
    public String sign;

    ...getter/setter...
}

以上就定義了我們一些基本驗證需要的類、介面、註解

接下來我們要做的就是定義一個基於hibernate-validator的驗簽註解驗證器SignValidator。

/**
 * 等於驗簽註解驗證器
 *
 * @author he
 * @since 1.0.0
 */
public class SignValidator implements ConstraintValidator<Sign, SignBean> {

    private static Logger logger = LoggerFactory.getLogger(SignValidator.class);

    private SignValidation signValidation;

    @Override
    public void initialize(Sign constraintAnnotation) {
        try {
            signValidation =  constraintAnnotation.value().newInstance();
        } catch (InstantiationException e) {
            logger.error(e.getMessage()+":例項化簽名管理器失敗。");
        } catch (IllegalAccessException e) {
            logger.error(e.getMessage()+":例項化簽名管理器失敗。");
        }finally{
            if (signValidation == null) {
                signValidation = new DefaultSignValidation();
            }
        }
    }

    @Override
    public boolean isValid(SignBean value, ConstraintValidatorContext context) {
        return signValidation.validation(value);
    }
}

這樣我們就定義好了一個自定義的驗證器。如何使用呢?很簡單,因為我的這個驗證器是針對於實體物件進行驗證的,那麼如何才能自己需要的實體進行驗證呢,只需要做一步操作,就是繼承SignBean這個物件即可。例如:

public class UserBean extends SignBean {

    @NotEmpty(message="姓名不能為空")
    private String name;

    @Range(min=20,max=120,message="年齡在20到120歲之間")
    private int age;

    ...getter/setter...

}

如果需要重新自己定義一個驗證器,只需要實現SignValidation介面即可,然後實現validation方法,通過在SignBean子類實體物件,覆蓋SignBean的@sign註解的value即可。

@Sign(value = Md5SignValidation.class,message="Md5驗證失敗")
public class UserBean extends SignBean {

    @NotEmpty(message="姓名不能為空")
    private String name;

    @Range(min=20,max=120,message="年齡在20到120歲之間")
    private int age;

    ...getter/setter...
}

以上就是我的整個思路以及實現過程,不過這樣做有一些缺陷,就是在實現過程中,實體上面的註解不能覆蓋,也就是說,如果我在SignBean使用了Sign註解,那麼我其它子類中也有這個註解,就都會驗證全部通過才會繼續,否則驗證不通過。個人想法是SignBean做一個超類,沒有新增@sign,類中只有一些必要的加簽欄位,然後做一些驗證物件分類,類如Md5Bean然後實現Md5驗證器。

@Sign(message=”md5驗證失敗”,value=Md5SignValidation.class)
public class Md5Bean extends SignBean{
//專屬驗證欄位
}

public class UserBean extends Md5Bean {

@NotEmpty(message="姓名不能為空")
private String name;

@Range(min=20,max=120,message="年齡在20到120歲之間")
private int age;

...getter/setter...

}

歡迎留言!原始碼地址

相關推薦

基於SpringMVC+hibernate-validator實現實現動態簽名驗證

首先我這個標題的意思先大家說說,我想要做的事情。 例如:我現在提供一個api給別人使用,然後api可能存在加簽、解籤、驗籤等過程,而且假設我不同的接入者使用了不同的簽名規則MD5或者RAS,並且針對不同的bean,加簽的欄位也不同。 問題1:如何選擇實現動態

基於SpringMVC 和MyBatis的實現省份城市之間的動態切換

實現選擇省份城市也跟著動態變化 1.建立資料庫 我的例子是:三個屬性scode(唯一標識一個省份或一個城市),sname(省份或城市的名稱),pcode(省份的為0,城市的為省份的scode) 2.在

JSR303的資料校驗-Hibernate Validator方式實現

1.什麼是JSR303? JSR303是java為bean資料合法性校驗所提供的一個標準規範,叫做Bean Validation. Bean Validation是一個執行時的資料校驗框架,在驗證之後驗證的錯誤資訊會被馬上返回。 2.實現方式:Hibernate Validator

SpringMVC Hibernate validator使用以及自定義校驗器註解

Hibernate validator使用以及自定義校驗器註解 Hibernate Validator常用註解 1.建立自定義校驗器 import javax.validation.Constraint; import javax.validation.Payloa

Java使用jxl的api實現excel動態資料驗證及匯入匯出

首先從優缺點上來說 一、jxl 優點: Jxl對中文支援非常好,操作簡單,方法看名知意。 Jxl是純javaAPI,在跨平臺上表現的非常完美,程式碼可以再windows或者Linux上執行而無需重新編寫 支援Excel 95-2000的所有版本(網上說目前可以支援Ex

SpringMVC案例2----基於spring2.5的註解實現

turn ddl mon ret load getc inpu aspectj mysql 和上一篇一樣,首先看一下項目結構和jar包 web.xml <?xml version="1.0" encoding="UTF-8"?> <web-a

基於JDK實現動態代理

  JDK動態代理是基於java.lang.reflect.*包提供的方式,他必須藉助一個接口才能產生代理物件,所以先定義介面: 實現類 ​​​​​ 此時可以開始實現動態代理了,首先建立起真實物件和代理物件的關係,然後實現代理邏輯。

Spring MVC利用Hibernate Validator實現後端資料校驗

        吐槽一下,網上坑好多啊!不過採坑才能學習,寫bug能力-1。 JSR 303、JSR 349與Bean Validator         籠統來說,就是Java規定了一套關於驗證器的API,

基於springMVC+AJAX+bootstraptable實現上傳檔案和客戶端分頁

1 首先看一下上傳表格程式碼,主要程式碼如下: <form method="post" enctype="multipart/form-data" id="orderform"> <div class="col-md-6 col-sm-12"&

springMVC基於hibernate validator的表單統一校驗

具體實現: 1、本測試專案採用maven工程。在pom.xml檔案中增加對validator.jar依賴的引入 由於這個專案是分散式的 所以我在parent專案的pom檔案中新增jar包 <properties> <version-h

基於springMVC的計算機學科點規章制度管理子系統的設計與實現基於java畢業設計

**基於springMVC的計算機學科點規章制度管理子系統的設計與實現,基於java畢業設計** 基於springMVC的計算機學科點規章制度管理子系統的設計與實現mysql資料庫建立語句 基於springMVC的計算機學科點規章制度管理子系統的設計與實現oracle資料庫建立

基於VC++2010實現雜湊簽名驗證

                數字簽名即如何給一個計算機檔案進行簽字。數字簽字可以用對稱演算法實現,也可以用公鑰演算法實現。但前者除了檔案簽字者和檔案接受者雙方,還需要第三方認證,較麻煩;通過公鑰加密演算法的實現方法,由於用祕密金鑰加密的檔案,需要靠公開金鑰來解密,因此這可以作為數字簽名,簽名者用祕密金鑰加

基於Upsync模組實現Nginx動態配置

題圖:By Federico Respini From Unsplash Upsync是新浪微博開源的基於Nginx實現動態配置的三方模組。Nginx-Upsync-Module的功能是拉取Consul的後端server的列表,並動態更新Nginx的路由資訊。此模組不依賴於任何第三方模組。Cons

Hibernate+SpringMVC+Spring+分頁實現留言管理專案

專案結構: 這裡使用到了Mysql資料庫 所用到的包:略。 首先進行springmvc.xml的配置,注意資料庫密碼要改為自己的。 <beans xmlns="http://www.springframework.org/schema/be

spring+springmvc+hibernate,實現分頁功能

效果圖 核心程式碼如下: pagebean.java import java.util.List; public class PageBean<T> { //已知資料 private int pageNum; //當前頁,從請求那邊傳過

用Maven整合SpringMVC+Spring+Hibernate 框架,實現簡單的插入資料庫資料功能

一、搭建開始前的準備 1、我用的MyEclipse2014版,大家也可以用IDEA。 2、下載Tomcat(免安裝解壓包)、MySQL(zip包下載地址 免安裝解壓包,好處就是雙擊啟動,最後我會把bat的啟動發給大家)、用的Navicat for MySQL的MySQL的圖

基於Spring+JMX+Tomcat實現資源動態管理

基於Spring+JMX+Tomcat實現資源動態管理 JMX(Java管理擴充套件)用於管理資源、裝置網路等。遠端管理程式可以提供執行態時修改程式的屬性或者呼叫程式的方法。本文基於JMX,結合Spr

基於SpringMVC框架使用ECharts3.0實現折線圖,柱狀圖,餅狀圖,的繪製

頁面部分:<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l

J2EE專案使用自定義註解實現基於SpringMVC + Mybatis + Mysql的讀寫分離

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/

Springmvc+hibernate+spring簡單例項實現(個人編譯通過)

自己花了兩天時間去網上查找了相關資料,搭建的一個綜合springmvc、hibernate和spring三種框架型別的環境,進行了一些簡單的例項實踐,下面貼出搭建步驟和程式碼,方便大家交流學習,也方便日後自己回來查閱 1.建立一個Java網站,建立的網站型別為D