溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

springboot+dubbo+validation 進(jìn)行rpc參數(shù)校驗(yàn)的實(shí)現(xiàn)方法

發(fā)布時(shí)間:2020-09-08 15:42:49 來源:腳本之家 閱讀:505 作者:雙斜杠少年 欄目:編程語言

注意:本文dubbo 版本 2.8.4 springboot 版本 2.0.4.RELEASE

項(xiàng)目結(jié)構(gòu)

  • test-rest (前端消費(fèi)著,controller 層,springboot+maven項(xiàng)目)
  • test-api (dubbo服務(wù) 的 api ,只記錄 service 接口和 model ,maven 項(xiàng)目)
  • test-provider(dubbo 服務(wù)提供者,實(shí)際的數(shù)據(jù)庫操作及業(yè)務(wù)層, springboot+maven項(xiàng)目 )

背景:

使用springmvc做restful,使用dubbo做rpc,restful中調(diào)用大量的rpc,數(shù)據(jù)驗(yàn)證會(huì)在這兩個(gè)地方,一個(gè)是restful層面,一個(gè)是rpc層面,restful層面使用springmvc默認(rèn)的集成hibernate-validator來實(shí)現(xiàn),參數(shù)開啟驗(yàn)證只需要加入@Validated param。dubbo 使用 rpc 的校驗(yàn)

dubbo rpc層面采用的是JSR303標(biāo)準(zhǔn)注解驗(yàn)證,通過hibernate-validator實(shí)現(xiàn),dubbo中開啟validation也有兩個(gè)方式,一個(gè)是在consumer端,一個(gè)是在provider`端。

開啟dubbo 的服務(wù)端校驗(yàn)時(shí),調(diào)用dubbo 的服務(wù)時(shí)會(huì)在服務(wù)端進(jìn)行參數(shù)校驗(yàn),如果在consumer 端也開啟了校驗(yàn)則調(diào)用服務(wù)時(shí)也會(huì)在 consumer 端進(jìn)行校驗(yàn)

dubbo 的rpc 校驗(yàn) (服務(wù)端開啟)

首先配置dobbo 的rpc 層校驗(yàn)

1.引入依賴,

 <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
    </dependency>

2.在api 的model 上添加注解

import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import java.io.Serializable;

public class UserSaveArgs implements Serializable {

  private static final long serialVersionUID = -5457103531947646047L;
  @NotEmpty(
      message = "用戶名不能為空")
  @Pattern(regexp = Constants.USERNAME_PATTERN, message = "用戶名格式有誤")
  private String userName;
  @NotEmpty(
      message = "手機(jī)號(hào)不能為空")
  @Pattern(regexp = Constants.PHONTE_NUMBER_PATTERN, message = "手機(jī)號(hào)編碼格式有誤")
  private String phoneNumber;
  @NotNull(
      message = "年齡不能為空")
  @Min(value = 0, message = "年齡不能小于0")
  private Integer age;
  
  //get set 省略

在dubbo 配置文件 provider.xml 中開啟驗(yàn)證 validation=“true”

  <dubbo:provider delay="-1" timeout="5000" threads="600" threadpool="fixed" loadbalance="roundrobin" accesslog="true"
          retries="0" validation="true"/>

消費(fèi)端開啟

由于消費(fèi)端引入了服務(wù)端的api 所以在消費(fèi)端開啟校驗(yàn)時(shí)只需在consumer.xml 中開啟驗(yàn)證即可 validation=“true”

consumer 端開啟了校驗(yàn)則在調(diào)用服務(wù)時(shí)會(huì)在 consumer 端進(jìn)行參數(shù)校驗(yàn),不使用provider的資源進(jìn)行校驗(yàn)

<dubbo:consumer check="false" timeout="60000" retries="0" validation="true"/>

配置自定義異常處理解析 rpc 校驗(yàn)異常

@ControllerAdvice
public class DefaultExceptionHandler {
 
 @ExceptionHandler({RpcException.class})
  @ResponseBody
  @ResponseStatus(HttpStatus.OK)
  public ResponseEntity RpcException(Exception ex, Model model) {
    logger.error("rpc接口參數(shù)校驗(yàn)異常。{}", ex.getMessage());
    String errMsg = ((ConstraintViolationException) ex.getCause()).getConstraintViolations()
        .iterator().next().getMessage();
    //ResponseEntity 為自定義的返回類,非springframework.http.ResponseEntity,當(dāng)然此處可以自己定義返回類,只需將 異常信息 errMsg 返回即可
    return ResponseEntity.error(ARG_ERROR_CODE, errMsg);
  }
}

Controller 驗(yàn)證

也就是 test-rest 項(xiàng)目 由于是dubbo的消費(fèi)者項(xiàng)目,也是springboot 項(xiàng)目。由于前端傳遞的參數(shù)需要在 此層包裝后進(jìn)行調(diào)用服務(wù)。所以驗(yàn)證前端傳遞的參數(shù)時(shí) 可以選擇使用 Springboot + validation 進(jìn)行校驗(yàn)

Spring3支持JSR-303驗(yàn)證框架,JSR-303 是Java EE 6 中的一項(xiàng)子規(guī)范,叫做BeanValidation,官方參考實(shí)現(xiàn)是hibernate Validator(與Hibernate ORM 沒有關(guān)系),JSR 303 用于對(duì)Java Bean 中的字段的值進(jìn)行驗(yàn)證。

具體配置參照博客:springboot 使用校驗(yàn)框架validation校驗(yàn)

小問題

test-rest 和 test-provider 都引用了test-api 。如果test-rest 層的入?yún)⑶『门c test-provider的服務(wù)調(diào)用入?yún)⑾嗤瑒t此時(shí)仍需在 test-rest 項(xiàng)目中 新建 入?yún)⒌?Java bean。

雖然 test-rest 的java bean 和 test-api 的Java bean 相同。但是Spring3 在解析的時(shí)候不能獲取到 test-api 的Java bean 校驗(yàn)注解。所以需要校驗(yàn)的時(shí)候仍然需要在 test-rest 項(xiàng)目中創(chuàng)建一個(gè) 和 test-api 的Java bean 相同 的java bean

附錄: 檢驗(yàn)注解及含義

//(1)空檢查
@Null 驗(yàn)證對(duì)象是否為null
@NotNull 驗(yàn)證對(duì)象是否不為null, 無法查檢長度為0的字符串
@NotBlank 檢查約束字符串是不是Null還有被Trim的長度是否大于0,只對(duì)字符串,且會(huì)去掉前后空格.
@NotEmpty 檢查約束元素是否為NULL或者是EMPTY.
//(2)Booelan檢查
@AssertTrue 驗(yàn)證 Boolean 對(duì)象是否為 true
@AssertFalse 驗(yàn)證 Boolean 對(duì)象是否為 false
//(3)長度檢查
@Size(min=, max=) 驗(yàn)證對(duì)象(Array,Collection,Map,String)長度是否在給定的范圍之內(nèi)
@Length(min=, max=) 驗(yàn)證字符串的長度在min和max范圍之內(nèi).
//(4)日期檢查
@Past 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之前,驗(yàn)證成立的話被注釋的元素一定是一個(gè)過去的日期
@Future 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之后 ,驗(yàn)證成立的話被注釋的元素一定是一個(gè)將來的日期
@Pattern 驗(yàn)證 String 對(duì)象是否符合正則表達(dá)式的規(guī)則,被注釋的元素符合制定的正則表達(dá)式,regexp:正則表達(dá)式 flags: 指定 Pattern.Flag 的數(shù)組,表示正則表達(dá)式的相關(guān)選項(xiàng)。
//(5)數(shù)值檢查
建議使用在Stirng,Integer類型,不建議使用在int類型上,因?yàn)楸韱沃禐?"時(shí)無法轉(zhuǎn)換為int,但可以轉(zhuǎn)換為Stirng為"",Integer為null
@Min 驗(yàn)證 Number 和 String 對(duì)象是否大等于指定的值
@Max 驗(yàn)證 Number 和 String 對(duì)象是否小等于指定的值
@DecimalMax 被標(biāo)注的值必須不大于約束中指定的最大值. 這個(gè)約束的參數(shù)是一個(gè)通過BigDecimal定義的最大值的字符串表示.小數(shù)存在精度
@DecimalMin 被標(biāo)注的值必須不小于約束中指定的最小值. 這個(gè)約束的參數(shù)是一個(gè)通過BigDecimal定義的最小值的字符串表示.小數(shù)存在精度
@Digits 驗(yàn)證 Number 和 String 的構(gòu)成是否合法
@Digits(integer=,fraction=) 驗(yàn)證字符串是否是符合指定格式的數(shù)字,interger指定整數(shù)精度,fraction指定小數(shù)精度。
@Range(min=, max=) 被指定的元素必須在合適的范圍內(nèi)
@Valid 遞歸的對(duì)關(guān)聯(lián)對(duì)象進(jìn)行校驗(yàn), 如果關(guān)聯(lián)對(duì)象是個(gè)集合或者數(shù)組,那么對(duì)其中的元素進(jìn)行遞歸校驗(yàn),如果是一個(gè)map,則對(duì)其中的值部分進(jìn)行校驗(yàn).(是否進(jìn)行遞歸驗(yàn)證)
@CreditCardNumber信用卡驗(yàn)證
@Email 驗(yàn)證是否是郵件地址,如果為null,不進(jìn)行驗(yàn)證,算通過驗(yàn)證。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=

當(dāng)然也可以自定義校驗(yàn)注解:

此處本文不做展示,如需自定義校驗(yàn)注解可查閱參考文檔

參考文檔:

https://www.jb51.net/article/170692.htm

https://www.jb51.net/article/155033.htm

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

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI