@ValidアノテーションはSpringで何を示していますか?


88

次の例では、ScriptFileパラメーターに@Valid注釈が付けられています。

@Validアノテーションは何をしますか?

@RequestMapping(value = "/scriptfile", method = RequestMethod.POST)    
public String create(@Valid ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        
    if (result.hasErrors()) {        
        modelMap.addAttribute("scriptFile", scriptFile);            
        modelMap.addAttribute("showcases", ShowCase.findAllShowCases());            
        return "scriptfile/create";            
    }        
    scriptFile.persist();        
    return "redirect:/scriptfile/" + scriptFile.getId();        
}    

回答:


63

検証用です。

検証ユーザー入力をモデルにバインドした後、モデルを検証するのが一般的です。Spring 3は、JSR-303による宣言型検証のサポートを提供します。このサポートは、HibernateValidatorなどのJSR-303プロバイダーがクラスパスに存在する場合に自動的に有効になります。有効にすると、Controllerメソッドパラメーターに@Validアノテーションを付けるだけで、検証をトリガーできます。着信POSTパラメーターをバインドした後、AppointmentFormが検証されます。この場合、日付フィールドの値がnullではなく、将来発生することを確認します。


詳細については、こちらをご覧ください:http
//blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/


37

上記の回答に加えて、以下をご覧ください。AppointmentFormdate列には、いくつかの注釈が付けられています。(この場合はと)の@Valid検証をトリガーする注釈を付けることによって。これらの注釈は、さまざまなJSR-303プロバイダー(Hibernate、Springなど)から取得できます。AppointmentForm@NotNull@Future

    @RequestMapping(value = "/appointments", method = RequestMethod.POST)
    public String add(@Valid AppointmentForm form, BindingResult result) {
        ....
    }

    static class AppointmentForm {

        @NotNull @Future
        private Date date;
    }

1
私は同様のコードを持っています。パラメータを削除し@ValidましたApplicationFormが、それでも検証はdate(として設定されたnull)フィールドで実行されました。説明してください。
lupchiazoem

18

@Validそれ自体は春とは何の関係もありません。これはBeanValidation仕様の一部です(いくつかありますが、最新のものは2017年下半期のJSR 380です)が、@Valid非常に古く、JSR303から派生しています。

ご存知のとおり、Springは一般的にすべての異なるJSRおよびJavaライブラリー(JPA、JTA、Cachingなどを考えてください)との統合を提供するのに非常に優れており、もちろんそれらの人も検証を行いました。これを容易にする重要なコンポーネントの1つは、MethodValidationPostProcessorです。

質問に答えようとする@Validことは、オブジェクトのトップレベルの要素だけでなく、複雑なグラフを検証する場合に、いわゆる検証カスケードに非常に便利です。もっと深く行きたいときはいつも、を使わなければなりません@Valid。それがJSRが指示するものです。Springは、いくつかの小さな逸脱でこれに準拠します(たとえば、RestControllerメソッドの@Validated代わり@Validに配置して検証が機能しますが、通常の「サービス」Beanには同じことが当てはまりません)。


しかし、何が検証されますか?

@nephewtom、詳しく説明してください。何を明確にしたいですか?
yuranos

JSR 303:Bean Validation、beanvalidation.org / 1.0 / specを読みました が、それでも、で実行される検証がわかりませんScriptFile scriptFile

その中のScriptFileにはおそらくたくさんのフィールドがあり、それらのフィールドにも注釈が付いています。ここで検証が始まります。元の質問に基づいて、ScriptFileクラス内に正確に何があるかは明確ではありません。
yuranos

わかりました、ありがとう。そのフィールドが文字列、整数、およびBeanであるかどうかを検証できる例を挙げていただけますか?

17

IIRC @Validは、Springアノテーションではなく、JSR-303アノテーション(Bean Validation標準)です。基本的に、メソッドに送信するデータが有効かどうかをチェックします(scriptFileを検証します)。


2
「scriptFileを検証する」とはどういう意味ですか?nullでないか、構文があるか、コンテンツがあるかを確認してください。言い換えれば、それは何をどのように検証しますか?ユーザーは何かを実装する必要がありますか?どこで情報を入手できますか?ありがとうございました!

@nephewtomの質問に答えてください。「何に対して」という欠落している要点を検証するには、十分な答えではありませんか?
MONAMI

2
public String create(@Valid @NotNull ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        

@NotNullしたがって、条件が不要な場合、この注釈は有効だと思います。


2

私はあなたの質問がどこに向かっているのか知っていると思います。そして、この質問はグーグルの検索メイン結果にポップアップする質問なので、@ Validアノテーションが何をするのかについてわかりやすい答えを出すことができます。

@Validの使用方法に関する3つのシナリオを紹介します

モデル:

public class Employee{
private String name;
@NotNull(message="cannot be null")
@Size(min=1, message="cannot be blank")
private String lastName;
 //Getters and Setters for both fields.
 //...
}

JSP:

...
<form:form action="processForm" modelAttribute="employee">
 <form:input type="text" path="name"/>
 <br>
 <form:input type="text" path="lastName"/>
<form:errors path="lastName"/>
<input type="submit" value="Submit"/>
</form:form>
...

シナリオ1のコントローラー:

     @RequestMapping("processForm")
        public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
        return "employee-confirmation-page";
    }

このシナリオでは、lastNameフィールドを空にしてフォームを送信した後、検証ルールを適用しているが、それをまったく処理していないため、エラーページが表示されます。

上記のエラーの例: 例外ページ

シナリオ2のコントローラー:

 @RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee,
BindingResult bindingResult){
                return bindingResult.hasErrors() ? "employee-form" : "employee-confirmation-page";
            }

このシナリオでは、その検証のすべての結果をbindingResultに渡すので、そのフォームの検証結果をどう処理するかを決めるのはあなた次第です。

シナリオ3のコントローラー:

@RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
                return "employee-confirmation-page";
            }
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> invalidFormProcessor(MethodArgumentNotValidException ex){
  //Your mapping of the errors...etc
}

このシナリオでは、最初のシナリオのようにエラーを処理していませんが、フォームモデルの処理時に@Validがトリガーする例外を処理する別のメソッドにそれを渡します。これをチェックして、マッピングなどをどうするかを確認しください。

要約すると:何もしないで、独自の@Validよりそのトリガー検証JSR 303の注釈付きフィールド(の検証@NotNull、@email、@size、など...)、あなたはまだ何をすべきかの戦略を指定する必要があります上記の検証の結果とともに。

これでつまずくかもしれない人々のために何かをクリアすることができたと思います。


1

ただ、上記の回答に追加して、Webアプリケーションで @valid検証するBeanは、検証注釈などでアノテートされた場合に使用され@NotNull@Email(注釈を休止状態)、ユーザからの入力を取得しながら、ときに値を検証することができ、その結果を結合すると、検証を持っています結果。 bindingResult.hasErrors()検証が失敗したかどうかを通知します。


1

上記に記載されていない@Validのもう1つの便利な側面は、(つまり、Postmanを使用してエンドポイントをテストする)@Validが、ほとんど読めないテキストのブロブではなく、フォーマットされたJSONに誤ったREST呼び出しの出力をフォーマットすることです。これは、ユーザー向けに商用消費可能なAPIを作成する場合に非常に役立ちます。


1

@Valid特に春の作品の詳細を追加したいと思いました。

Springでの検証について知りたいことはすべて、https://reflectoring.io/bean-validation-with-spring-boot/で明確かつ詳細に説明されています@Valid、リンクの場合の動作の答えをコピーします低下する。

@Valid注釈は、それらを検証するために、残りのコントローラメソッドで変数に追加することができます。検証できる変数には次の3種類があります。

  • リクエスト本文、
  • パス内の変数(例:/ foos / {id}のid)および、
  • クエリパラメータ。

では今...春はどのように「検証」するのでしょうか?クラスのフィールドに特定のアノテーションを付けることで、フィールドに制約を定義できます。次に、そのクラスのオブジェクトをバリデーターに渡します。バリデーターは、制約が満たされているかどうかをチェックします。

たとえば、次のようなコントローラーメソッドがあるとします。

@RestController
class ValidateRequestBodyController {

  @PostMapping("/validateBody")
  ResponseEntity<String> validateBody(@Valid @RequestBody Input input) {
    return ResponseEntity.ok("valid");
  }

}

つまり、これは応答本文を受け取るPOSTリクエストであり、その応答本文をクラスにマッピングしていますInput

これがクラスInputです:

class Input {

  @Min(1)
  @Max(10)
  private int numberBetweenOneAndTen;

  @Pattern(regexp = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$")
  private String ipAddress;
  
  // ...
}

@ValidアノテーションはnumberBetweenOneAndTen、最小アノテーションと最大アノテーションのために整数が1から10の間であることを確認することにより、コントローラーに渡されたデータを検証するようにSpringに指示します。また、渡されたIPアドレスがアノテーションの正規表現と一致することを確認します。

補足:正規表現は完全ではありません。255より大きい3桁の数値を渡すことができますが、それでも正規表現と一致します。


クエリ変数とパス変数を検証する例を次に示します。

@RestController
@Validated
class ValidateParametersController {

  @GetMapping("/validatePathVariable/{id}")
  ResponseEntity<String> validatePathVariable(
      @PathVariable("id") @Min(5) int id) {
    return ResponseEntity.ok("valid");
  }
  
  @GetMapping("/validateRequestParameter")
  ResponseEntity<String> validateRequestParameter(
      @RequestParam("param") @Min(5) int param) { 
    return ResponseEntity.ok("valid");
  }
}

この場合、クエリ変数とパス変数は単純なクラスではなく整数であるため、@Min(5)を使用する代わりに、パラメーターに制約アノテーションを配置します@Valid

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.