Java でエレガントなパラメータ検証を実装する方法

王林
リリース: 2023-05-19 19:43:04
転載
2515 人が閲覧しました

1. はじめに

メソッドのパラメータを確認するための、最も単純かつ最も乱暴な書き方は次のとおりです:

    public static void utilA(String a,BigDecimal b){
        if (StringUtils.isEmpty(a)){
            System.out.println("a不可为空");
            return;
        }
        if (b == null){
            System.out.println("b不可为空");
            return;
        }
        if (b.compareTo(BigDecimal.ZERO) != 1){
            System.out.println("b的取值范围不正确");
            return;
        }
        System.out.println("do something");
    }
ログイン後にコピー

機能的にはまったく問題ありません視界の。

しかし、コードの長期的な保守性という観点から見ると、コードの再利用率は低く、検証ルールが多すぎると保守が難しく、見た目も不格好になります。追求しても、そのような大佗は依然として受け入れがたいものです。

Preconditions (com.google) などの解決策はいくつかありますが、すべてのシナリオに適応するのは難しく、本来の使用感ほど快適ではありません。

2. パラメーターをエレガントに検証する方法

Spring は、明確なセマンティクス (入力パラメーターの検証、戻り値の検証) を備えたエレガントなメソッドレベルの検証を公式に推奨しています

2.1 公式ガイダンス

Spring 公式の SpringBoot ドキュメントで、パラメータの検証 (Validation) について示されている解決策は次のとおりです。

@Service
@Validated
public class MyBean {
 
    public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
            Author author) {
        ...
    }
 
}
ログイン後にコピー

Spring Boot 公式サイトのドキュメント「37. Validation」

つまり、JSR-303 仕様を使用し、パラメータ検証にアノテーションを直接使用します。

(JSR-303 は Bean Validation と呼ばれる Java EE 6 のサブ標準であり、公式リファレンス実装は Hibernate Validator です)

2.2 アノテーションの使用手順

2.2.1. アノテーションの概要

単純型パラメーター (非 Bean) の場合、アノテーションを使用してパラメーターの直前に制約ルールを追加します。アノテーションは次のとおりです:

@AssertTrue / @AssertFalse

検証対象フィールド: boolean

アノテーションの説明: 値が true/ であるかどうかを検証します。 false

##@DecimalMax / @DecimalMin

検証対象フィールド: BigDecimal、BigInteger、String、byte、short、int、long

注釈: 検証value 指定された 10 進数値以下かどうかに関係なく、小数には精度の問題があることに注意してください

@Digits

検証対象フィールド: BigDecimal、BigInteger 、String、byte、short、int、long

アノテーション: 値の数値構成が正当であるかどうかを検証します

属性の説明: integer: 整数部分の桁数を指定します。小数部: 小数部の桁数を指定します。

@Future / @Past

検証可能なフィールド: 日付、カレンダー

注釈: 値が現在時刻より前か後かを検証します

プロパティの説明: Public

@Max / @Min

適用可能な検証フィールド: BigDecimal、BigInteger、String、byte、short、int、long

アノテーション: 値が指定された整数値以下であるかどうかを確認します

属性の説明: Public

注: ではなく、Stirng の整数型を使用することをお勧めします。フォームによって送信された値は int

@NotNull / @Null

検証対象フィールド: 参照データ型#に変換できないため、int 型を使用することをお勧めします。

# #アノテーションの説明: 値が非 null/空であるかどうかを確認します。

属性の説明: Public

@NotBlank

制約文字列が Null であるかどうかを確認し、トリミングされた文字列の長さが 0 より大きいかどうか (文字列の場合のみ、先頭と末尾のスペースは削除されます)

@NotEmpty

制約要素が Null か EMPTY かを確認します。 @NotBlank と @NotEmpty の違い: NotEmpty ではスペース (" ") が使用できますが、NotBlank は検証例外をスローします

@Pattern

検証対象フィールド: 文字列

アノテーション: 値に正規表現が付いているかどうかを検証

##属性の説明: regexp:正規表現 flags: の関連オプションを表す Pattern.Flag を指定する配列正規表現。

@サイズ

検証対象フィールド: 文字列、コレクション、マップ、配列

注釈: 値が長さの要件を満たしているかどうかを検証します

属性の説明: max: 最大長を指定し、min: 最小長を指定します。

@Length(min=, max=)

: 文字列型に特別に適用されます

@Valid

検証適用可能なフィールド: 関連オブジェクトを再帰的に検証します。

注: 関連オブジェクトがコレクションまたは配列の場合は、その中の要素が再帰的に検証されます。マップの場合は、値の部分が検証されます。(再帰を実行するかどうか)検証)

#属性の説明: なし

#@Range(min=, max=)

指定された要素は適切な範囲内にある必要があります

@CreditCardNumberクレジット カード検証

@Email 電子メール アドレスであるかどうかを検証します。null の場合、検証は実行されず、検証に合格します。

##@URL(protocol=,host=, port=,regexp=, flags=)

2.2.2 使用

1. 依存関係を導入する

 <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.5.Final</version>
        </dependency>
ログイン後にコピー

2. 対応するフィールドに注釈を追加する メソッドが呼び出されたときに、渡された実際のパラメーターが制約ルールと一致しない場合は、ConstraintViolationException が直接スローされます。パラメータの検証に失敗しました。

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
 
/**
 * @Author: wangxia
 * @Date: 2021/10/20 16:30
 */
public class TestPerson {
 
    @NotEmpty(message = "用户名不能为空")
    private String username;
 
    @Min(value = 0,message = "年龄不能小于0岁")
    @Max(value =150,message = "年龄不能大于150岁")
    private int age;
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
}
ログイン後にコピー
3.. Bean 型パラメータの場合、Bean 内の各フィールドに制約アノテーションを追加し、メソッド パラメータの前に @Validated または @Valid アノテーションを追加します。例:

@RequestMapping("/")
@RestController
public class TestValidatController {
 
    @PostMapping("/testValid")
    public String testValid(@Validated @RequestBody TestPerson testPerson){
        return "测试成功";
    }
 
}
ログイン後にコピー

4. 例外を適切にキャッチします。このステップは省略できますが、要求時に 400 例外プロンプトとともに直接返されますが、これはあまりエレガントではありません。

@ControllerAdvice
@ResponseBody 
public class MethodArgumentNotValidHandel {
 
 
    @ExceptionHandler(value=MethodArgumentNotValidException.class)
    public JSONObject MethodArgumentNotValidHandler(HttpServletRequest request,
                                                    MethodArgumentNotValidException exception) throws Exception
    {
        JSONObject result=new JSONObject();
        result.put("code","fail");
        JSONObject errorMsg=new JSONObject();
        for (FieldError error : exception.getBindingResult().getFieldErrors()) {
            errorMsg.put(error.getField(),error.getDefaultMessage());
        }
        result.put("msg",errorMsg);
        return result;
    }
 
}
ログイン後にコピー

エレガントにキャプチャされた例外プロンプトを追加します:

エレガントにキャプチャされた例外プロンプトを追加しません:

Java でエレガントなパラメータ検証を実装する方法

以上がJava でエレガントなパラメータ検証を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート