偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

參數(shù)校驗(yàn)的六大神功!

開發(fā) 前端
"某一個(gè)周末下午,我接到電話,打開日志一看,??NullPointerException??堆棧里有38個(gè)不同位置的校驗(yàn)邏輯。

新手司機(jī)翻車實(shí)錄

"哥,注冊(cè)接口又被刷爆了!

"某一個(gè)周末下午,我接到電話,打開日志一看,NullPointerException堆棧里有38個(gè)不同位置的校驗(yàn)邏輯。

原來(lái)新人小王在Controller里寫滿了這樣的代碼:

// 典型錯(cuò)誤示范(轉(zhuǎn)載自某小廠祖?zhèn)鞔a)
public String register(UserDTO user) {
    if (user.getName() == null) {
        return"名字不能為空";
    }
    if (user.getAge() == null) {
        return"年齡不能為空";
    }
    if (user.getAge() < 18) {
        return"年齡不能小于18歲";
    }
    if (!user.getPhone().matches("^1[3-9]\\d{9}$")) {
        return"手機(jī)號(hào)不合法";
    }
    // ...后續(xù)還有20個(gè)if...
}

這才是代碼界的"九轉(zhuǎn)大腸"——每個(gè)入口都讓人窒息。

作為一位有很多開發(fā)經(jīng)驗(yàn)的老司機(jī),今天,老夫帶你修煉參數(shù)校驗(yàn)的6大神功。

圖片圖片

希望對(duì)你會(huì)有所幫助。

第一重:JSR規(guī)范基礎(chǔ)功

1.1 HibernateValidator瞬煉大法

可以使用Hibernate中Validator框架做參數(shù)校驗(yàn),具體代碼如下:

public class UserDTO {
    @NotBlank(message = "名稱要填,皮這一下很開心?")
    private String name;

    @NotNull
    @Min(value = 18, message = "未成年禁止入內(nèi)")
    @Max(60)
    private Integer age;

    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "這手機(jī)號(hào)是哪國(guó)來(lái)的?")
    private String phone;
}

// Controller層啟用校驗(yàn)(新手必知第一步)
@PostMapping("/register")
public Result register(@Valid @RequestBody UserDTO user) {
    // 業(yè)務(wù)代碼...
}

技術(shù)要點(diǎn)

  • 引入spring-boot-starter-validation依賴(調(diào)料包記得加)
  • @Valid注解要放在入?yún)?cè)(別貼在DTO類上)
  • 錯(cuò)誤信息會(huì)進(jìn)BindingResult(打掃戰(zhàn)場(chǎng)需要手動(dòng)處理)

第二重:全局異常擒龍手

2.1 統(tǒng)一異常攔截器

我們需要對(duì)異常進(jìn)行統(tǒng)一攔截。

這樣在出現(xiàn)參數(shù)校驗(yàn)異常,比如空指針時(shí),不會(huì)把服務(wù)的內(nèi)部錯(cuò)誤信息直接輸出給用戶。

通過(guò)@RestControllerAdvice和@ExceptionHandler注解實(shí)現(xiàn)統(tǒng)一異常攔截器的功能。

具體代碼如下:

@RestControllerAdvice
publicclass GlobalExceptionHandler {
    
    // 專治各種不服校驗(yàn)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValidException(MethodArgumentNotValidException e) {
        BindingResult result = e.getBindingResult();
        return Result.fail(result.getFieldError().getDefaultMessage());
    }
}

// 返回格式規(guī)范(示例)
publicclass Result<T> {
    private Integer code;
    private String msg;
    private T data;
    
    publicstatic <T> Result<T> fail(String message) {
        returnnew Result<>(500, message, null);
    }
}

反爬蟲機(jī)制

  • 禁止直接暴露字段名給前端(攻擊者會(huì)利用字段名信息)
  • 錯(cuò)誤信息字典化管理(后面會(huì)教國(guó)際化這招)

第三重:自定義校驗(yàn)屠龍技

3.1 手機(jī)/郵箱二元校驗(yàn)

有時(shí)候,Hibernate Validator框架或者其他校驗(yàn)框架定義的校驗(yàn)不滿足需求,我們需要自定義校驗(yàn)規(guī)則。

則可以自定義注解,實(shí)現(xiàn)ConstraintValidator接口,來(lái)實(shí)現(xiàn)具體的自定義的校驗(yàn)邏輯。

自定義注解@Contact在字段上使用。

具體代碼如下:

@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = ContactValidator.class)
public @interface Contact {
    String message() default "聯(lián)系方式格式錯(cuò)誤";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

// 校驗(yàn)邏輯實(shí)現(xiàn)(不要相信前端的下拉框?。?publicclass ContactValidator implements ConstraintValidator<Contact, String> {
    
    privatestaticfinal Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
    privatestaticfinal Pattern EMAIL_PATTERN = Pattern.compile("^\\w+@\\w+\\.\\w+$");

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return PHONE_PATTERN.matcher(value).matches() 
               || EMAIL_PATTERN.matcher(value).matches();
    }
}

六邊形戰(zhàn)士培養(yǎng)計(jì)劃

  • 可通過(guò)context.buildConstraintViolationWithTemplate()動(dòng)態(tài)修改錯(cuò)誤信息
  • 支持DI注入Spring管理的Bean(比如從數(shù)據(jù)庫(kù)加載正則)

第四重:分組校驗(yàn)北冥功

4.1 增刪改查不同校驗(yàn)規(guī)則

對(duì)于增刪改查中,對(duì)于實(shí)體對(duì)象中的同一個(gè)參數(shù),在不同的應(yīng)用場(chǎng)景中需要做不同分組校驗(yàn)。

具體代碼如下:

// 定義校驗(yàn)組別(劃分陣營(yíng))
publicinterface CreateGroup {}
publicinterface UpdateGroup {}

// DTO根據(jù)場(chǎng)景應(yīng)用分組
publicclass ProductDTO {
    @Null(groups = UpdateGroup.class)
    @NotNull(groups = CreateGroup.class)
    private Long id;

    @NotBlank(groups = {CreateGroup.class, UpdateGroup.class})
    private String name;
}

// 控制層按需激活校驗(yàn)組  
@PostMapping("/create")
public Result create(@Validated(CreateGroup.class) @RequestBody ProductDTO dto) {
    // 創(chuàng)建邏輯
}

多副本作戰(zhàn)手冊(cè)

  • Default組始終生效(除非使用groups顯式配置)
  • 妙用@ConvertGroup進(jìn)行分組轉(zhuǎn)換

第五重:跨界校驗(yàn)凌波微步

5.1 跨字段關(guān)系校驗(yàn)

如果存在跨字段關(guān)系校驗(yàn)的情況,即組合條件校驗(yàn),比如:用戶密碼和確認(rèn)密碼,可以將自定義注解作用在類上。

具體代碼如下:

@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface PasswordValid {
    String message() default "兩次密碼不一致";
    // ...
}

publicclass PasswordValidator implements ConstraintValidator<PasswordValid, UserDTO> {
    
    @Override
    public boolean isValid(UserDTO user, ConstraintValidatorContext context) {
        return user.getPassword().equals(user.getConfirmPassword());
    }
}

// 應(yīng)用到類級(jí)別
@PasswordValid
publicclass UserDTO {
    private String password;
    private String confirmPassword;
}

風(fēng)控新法

  • 適用于訂單金額與優(yōu)惠券匹配等業(yè)務(wù)規(guī)則
  • DDD值對(duì)象的天然場(chǎng)景

第六重:規(guī)則引擎之天機(jī)策

天機(jī)殿的自動(dòng)化戰(zhàn)場(chǎng)

新來(lái)的產(chǎn)品小妹指著參數(shù)校驗(yàn)文檔:"每次改個(gè)手機(jī)號(hào)正則都要等發(fā)版?

"我默默掏出了祖?zhèn)鞯囊?guī)則引擎。

這種政商聯(lián)動(dòng)的需求,是時(shí)候施展大型工程的必殺技了!

6.1 規(guī)則引擎的三層境界

第一境:硬編碼校驗(yàn)(青銅段位的if-else)第二境:配置化校驗(yàn)(黃金段位的數(shù)據(jù)庫(kù)規(guī)則表)第三境:熱力場(chǎng)作戰(zhàn)(王者段位的動(dòng)態(tài)規(guī)則引擎)

6.2 Drools天機(jī)大陣部署實(shí)錄

戰(zhàn)場(chǎng)場(chǎng)景:信貸額度動(dòng)態(tài)校驗(yàn)(每小時(shí)調(diào)整風(fēng)控模型) 。

天機(jī)規(guī)則文件如下:

// 天機(jī)規(guī)則文件(credit_rule.drl)
rule "白領(lǐng)貸基礎(chǔ)校驗(yàn)"
    when
        $req : LoanRequest(
            occupation == "白領(lǐng)", 
            salary > 10000, 
            age >= 25 && age <= 45
        )
    then
        $req.setRiskScore(-10); //加分項(xiàng)
end

rule "高危行業(yè)攔截"
    when
        $req : LoanRequest(
            industry in ("賭博業(yè)", "傳銷"), 
            location.contains("緬甸")
        )
    then
        throw new ValidationException("閣下莫非是緬北戰(zhàn)神?"); 
end

布陣心法

圖片圖片

陣法要訣

  1. 規(guī)則文件按業(yè)務(wù)線拆分(金融/電商/社交各立山頭)
  2. 使用kie-maven-plugin自動(dòng)編譯規(guī)則文件
  3. KieScanner監(jiān)聽規(guī)則變更(天機(jī)更新不重啟服務(wù))

6.3 SpringBoot接引天機(jī)大陣

法咒集成

@Configuration
publicclass DroolsConfig {
    
    @Bean
    public KieContainer kieContainer() {
        KieServices ks = KieServices.Factory.get();
        KieFileSystem kfs = ks.newKieFileSystem();
        
        // 加載天機(jī)卷軸(規(guī)則文件)
        Resource resource = new ClassPathResource("rules/credit_rule.drl");
        kfs.write(ks.getResources().newInputStreamResource(resource.getInputStream())
                    .setTargetPath("credit_rule.drl"));
        
        KieBuilder kieBuilder = ks.newKieBuilder(kfs).buildAll();
        return ks.newKieContainer(kieBuilder.getKieModule().getReleaseId());
    }
}

// Controller層調(diào)用天尊之力
@PostMapping("/apply")
public Result applyLoan(@RequestBody LoanRequest request) {
    kieSession.insert(request);
    kieSession.fireAllRules(); // 執(zhí)行天機(jī)推演
    return riskService.process(request);
}

天機(jī)沙箱防御

  1. 限制規(guī)則中eval()的使用次數(shù)(防CPU過(guò)載)
  2. 為每個(gè)請(qǐng)求創(chuàng)建獨(dú)立KieSession(防線程污染)
  3. 設(shè)置規(guī)則執(zhí)行超時(shí)熔斷(天機(jī)殿也有算不動(dòng)的時(shí)候)

6.4 天機(jī)策反制訣竅

某次上線后,規(guī)則引擎的神操作:

rule "特殊時(shí)段放水"
    when
        $req : LoanRequest(hour > 2 && hour < 5)
    then
        $req.setCreditLimit(50000); //給值夜班的兄弟開后門
end

反制方案

  1. 規(guī)則提交走審批流(太上長(zhǎng)老團(tuán)聯(lián)署制)
  2. 生產(chǎn)環(huán)境禁用update/modify關(guān)鍵字(防自動(dòng)奪舍)
  3. 規(guī)則版本回滾機(jī)制(祭出玄天寶鏡倒轉(zhuǎn)時(shí)空)

祖師爺級(jí)參數(shù)校驗(yàn)綱領(lǐng)

段位

招式名稱

修煉難度

適用場(chǎng)景

破壞力

青銅

if-else硬編碼

★☆☆

小型工具類

???

白銀

JSR注解大法

★★☆

常規(guī)CRUD

??

黃金

全局異常攔截

★★★

RESTful API

?

鉑金

定制校驗(yàn)規(guī)則

★★★☆

復(fù)雜業(yè)務(wù)規(guī)則

?

鉆石

組合條件校驗(yàn)

★★★★

跨字段業(yè)務(wù)約束

?

王者

規(guī)則引擎整合

★★★★★

動(dòng)態(tài)風(fēng)控場(chǎng)景

?

避坑法門

  1. 不過(guò)三:Controller層校驗(yàn)不要超過(guò)三層(應(yīng)該轉(zhuǎn)給Service)
  2. 見好就收:業(yè)務(wù)規(guī)則校驗(yàn)與基礎(chǔ)格式校驗(yàn)分離
  3. 防君子更防小人:服務(wù)端校驗(yàn)必須存在(前端校驗(yàn)是防君子用的)
  4. 語(yǔ)義明確:錯(cuò)誤提示避免暴露敏感信息(比如"用戶不存在"改為"賬號(hào)或密碼錯(cuò)誤")

最后提醒各位大俠:好的參數(shù)校驗(yàn)就像空氣——你平時(shí)感受不到它的存在,但一旦失去它,整個(gè)系統(tǒng)瞬間崩塌?。ùafields正提刀趕來(lái))


責(zé)任編輯:武曉燕 來(lái)源: 蘇三說(shuō)技術(shù)
相關(guān)推薦

2016-08-24 15:39:46

ownCloud存儲(chǔ)服務(wù)器

2024-10-22 14:42:14

2011-03-16 10:44:19

2013-08-23 10:18:06

Hadoop

2016-07-06 11:16:47

2010-09-09 10:54:58

2023-05-11 11:36:56

云計(jì)算云供應(yīng)商

2023-07-24 11:01:32

2013-08-23 10:42:03

Hadoop

2022-01-23 10:44:39

零信任網(wǎng)絡(luò)安全網(wǎng)絡(luò)攻擊

2023-08-31 22:12:51

低代碼隱患技術(shù)

2021-08-12 14:31:52

邊緣計(jì)算云計(jì)算數(shù)據(jù)

2010-09-25 15:22:19

DHCP故障處理

2010-08-16 10:14:23

云計(jì)算誤區(qū)

2010-07-30 13:15:17

Flex優(yōu)勢(shì)

2023-10-18 10:48:44

Python解釋器

2009-05-14 17:24:18

2010-07-06 09:48:34

六大UML圖

2019-04-29 13:22:58

數(shù)據(jù)保護(hù)GDPR數(shù)據(jù)安全

2023-08-22 13:38:13

云成本優(yōu)化公有云
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)