Spring Web MVC 3.0でwebappを実行していますが、そのシグネチャがおおよそ次のようなコントローラーメソッドをいくつか持っています。
@RequestMapping(value = "/{level1}/{level2}/foo", method = RequestMethod.POST)
public ModelAndView createFoo(@PathVariable long level1,
@PathVariable long level2,
@RequestParam("foo_name") String fooname,
@RequestParam(value = "description", required = false) String description);
検証を追加したい。たとえば、description
を特定の長さに制限するか、fooname
に特定の文字のみを含める必要があります。この検証が失敗した場合、チェックされていない例外をスローするのではなく、ユーザーにメッセージを返します(データをDAOレイヤーに浸透させるとどうなります)。私はJSR303を知っていますが、JSR303を使用したことがなく、SpringコンテキストでJSR303を適用する方法をよく理解していません。
私が理解したことから、別のオプションは@RequestBody
をドメインオブジェクト全体にバインドし、そこに検証制約を追加することですが、現在私のコードは上記のように個々のパラメータを受け入れるように設定されています。
このアプローチを使用して入力パラメーターに検証を適用する最も簡単な方法は何ですか?
それを行うために組み込まれているものは何もありません。とにかく notyet です。現在のリリースバージョンでは、自動検証を行う場合は、WebDataBinderを使用してパラメーターをオブジェクトにバインドする必要があります。 SpringMVCを使用している場合は、このタスクの最初の選択ではない場合でも、学ぶ価値があります。
次のようになります。
public ModelAndView createFoo(@PathVariable long level1,
@PathVariable long level2,
@Valid @ModelAttribute() FooWrapper fooWrapper,
BindingResult errors) {
if (errors.hasErrors() {
//handle errors, can just return if using Spring form:error tags.
}
}
public static class FooWrapper {
@NotNull
@Size(max=32)
private String fooName;
private String description;
//getset
}
クラスパスにHibernate Validator 4以降があり、デフォルトのディスパッチャセットアップを使用している場合は、「動作するはずです」。
コメントがかなり大きくなったため編集:
メソッドのシグネチャにあるオブジェクトのうち、「予想される」もののいずれでもないオブジェクトは、SpringがHttpRequest
、ModelMap
などの注入方法を知っているため、データバインドされます。これは、単純なケースでは、リクエストパラメータ名をBeanプロパティ名と照合し、セッターを呼び出すだけで実現されます。 @ModelAttribute
には個人的なスタイルのものがありますが、この場合は何もしていません。メソッドパラメータの@ValidとのJSR-303統合は、WebDataBinder
を介して接続されます。 @RequestBody
を使用している場合は、要求の本文に対してSpringが決定するコンテンツタイプに基づくオブジェクトマーシャラーを使用しています(通常はhttpヘッダーからのみ)。ディスパッチャーサーブレット(AnnotationMethodHandlerAdapter
本当に)は使用しません任意のマーシャラーの「検証スイッチを反転する」方法があります。 Webリクエストのコンテンツをメッセージコンバーターに渡すだけで、オブジェクトが返されます。 BindingResultオブジェクトは生成されないため、とにかくエラーを設定する場所はありません。
バリデータをコントローラにインジェクトし、取得したオブジェクトで実行するだけで、BindingResult
を生成するリクエストパラメータの@Valid
との魔法の統合はありません。
これは現在可能になっているようです(Spring 4.1.2で試しました) https://raymondhlee.wordpress.com/2015/08/29/validating-spring-mvc-request-mapping-method-parameters/を参照してください
上記のページから抽出:
MethodValidationPostProcessorをSpring @Configurationクラスに追加します。
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
@Validatedをコントローラークラスに追加する
@RequestParamの直前に@Sizeを使用します
@RequestMapping("/hi")
public String sayHi(@Size(max = 10, message = "name should at most 10 characters long") @RequestParam("name") String name) {
return "Hi " + name;
}
@ExceptionHandlerメソッドでConstraintViolationExceptionを処理する
検証する必要のあるリクエストパラメータが複数ある場合(Http[〜#〜] get [〜#〜]または[〜#〜] post [〜#〜])。 カスタムモデルクラスを作成し、@Validを一緒に使用することもできます@ModelAttributeでパラメーターを検証します。この方法で Hibernate Validator または javax.validator api を使用して、パラメーターを検証できます。次のようになります。
リクエスト方法:
@RequestMapping(value="/doSomething", method=RequestMethod.GET)
public Model dosomething(@Valid @ModelAttribute ModelRequest modelRequest, BindingResult result, Model model) {
if (result.hasErrors()) {
throw new SomeException("invalid request params");
}
//to access the request params
modelRequest.getFirstParam();
modelRequest.getSecondParam();
...
}
ModelRequestクラス:
class ModelRequest {
@NotNull
private String firstParam;
@Size(min = 1, max = 10, message = "You messed up!")
private String secondParam;
//Setters and getters
public void setFirstParam (String firstParam) {
this.firstParam = firstParam;
}
public String getFirstParam() {
return firstParam;
}
...
}
お役に立てば幸いです。