Springの3.1 MVCannotationDrivenを実装する方法は?
-
27-10-2019 - |
質問
これは、スプリング3.1のコード例です Spring Sourceブログ:XMLから@Configurationまで 私はアプリケーションに実装しようとしています(これは私ではなくスプリング2.0で行われたので、多くの学習です)。
@FeatureConfiguration
class MvcFeatures {
@Feature
public MvcAnnotationDriven annotationDriven(ConversionService conversionService) {
return new MvcAnnotationDriven().conversionService(conversionService)
.argumentResolvers(new CustomArgumentResolver());
}
// ...
}
しかし、私はそのポイントを理解することはできません .ArgumentResolvers(new CustomArgumentResolver()) そして、彼らのcustomargumentResolverは、bellowのように見えます。それのポイントは何ですか?
public class CustomArgumentResolver implements WebArgumentResolver {
@Override
public Object resolveArgument(MethodParameter param, NativeWebRequest request) throws Exception {
RequestAttribute attr = param.getParameterAnnotation(RequestAttribute.class);
if (attr != null) {
return request.getAttribute(attr.value(), WebRequest.SCOPE_REQUEST);
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}
解決
@garyfの回答に追加し、いくつかのポイントを明確にするために、Spring 2.5は注釈付きコントローラーを導入しました。これらの新しいコントローラーには、固定パラメーターのないメソッドがあります - この方法は、仕事をするために必要なパラメーターを宣言します。
たとえば、コントローラーの方法がジョブを行うために1つのことを必要としたとします - データベースのオブジェクトのIDを含む要求パラメーター。スプリング2.0では、次のようなものを実装する必要があります AbstractController.handleRequestInternal()
, 、例:
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
String id = request.getParameter("id");
MyThing obj = getObjById(id);
//... do stuff and return ModelAndView
}
春2.5はそれを簡単にしました:
@RequestMapping
public ModelAndView handle(String id) {
MyThing obj = getObjById(id);
//... do stuff and return ModelAndView
}
ここでは、必要なもののパラメーターのみを宣言します。
これまでのところ良いですが、これはカスタムです WebArgumentResolver
入ってくる。私が削除したいと言ってください getObjById
私のコントローラーから完全に、多分私はそれがコードをカバーすると思うかもしれないので、それは他の多くのコントローラー方法で使用されているかもしれません。代わりに、私はこれをしたい:
@RequestMapping
public ModelAndView handle(MyThing id) {
//... do stuff and return ModelAndView
}
さらにシンプルで、最小限のボイラープレートコードがあります。カスタム WebArgumentResolver
タイプのパラメーターを認識するアプリコンテキストに登録できます MyThing
, 、およびリクエストから情報を抽出する方法を知っています。 Springはそのリゾルバーを呼び出し、結果をコントローラーメソッドに渡します。
カスタムリゾルバーは一般的に使用されていませんが、適切な状況では非常に便利です。
質問の例は使用します CustomArgumentResolver
例のカスタムを解決します RequestAttribute
クラス。リゾルバーは要求属性を引き出し、それらをにバインドします RequestAttribute
オブジェクト。そのため、コントローラーメソッドパラメーターとして宣言できます。
他のヒント
WebArgumentResolver
Sは、MVCマップメソッドのパラメーターを解決する方法を指定する方法です。 MVCマップメソッドのパラメーターとしてカスタムオブジェクトを使用したい場合、Springは、独自の方法でそれをどのように理解するかを理解しようとします。通常、これはバインディングを通じて発生します。これは、あなたが送信するいくつかのHTTPパラメーターがオブジェクトのフィールドと一致し、スプリングがそれらを一致させ、あなたのために新しいオブジェクトを作成します。
送信されたパラメーターがメソッドパラメーターとそれほどきれいに一致しない状況がある場合、WebArgumentResolversはギャップを埋めるためにそこにあります。カスタムロジックを提供して、Springがそれを理解する必要がないようにします。
あなたの例では、PARAMは一致するようなパラメーターの1つです。このカスタムコードは、最初にパラメーターに@requestattributeアノテーションがあるかどうかを確認します。もしそうなら、カスタムコードはそのオブジェクトから値を引き出し、HTTPリクエストの属性として表示して返します。注釈はありません。そのメソッドは未解決の値を返します。これは、このWebargumentResolverがこの特定のパラメーターについて何も知らないことを示す単純に、Springは別の方法(バインディングなど)を試す必要があることを示します。