1

これはSpring3.1のコード例です。SpringSourceBlog:XMLから@Configurationまでアプリケーションに実装しようとしています(これは私ではなくSpring 2.0で行われたため、多くの学習が必要です)。

@FeatureConfiguration
class MvcFeatures {

    @Feature
    public MvcAnnotationDriven annotationDriven(ConversionService conversionService) {
        return new MvcAnnotationDriven().conversionService(conversionService)
            .argumentResolvers(new CustomArgumentResolver());
    }

    // ...

}

ただし、.argumentResolvers(new CustomArgumentResolver())のポイントが理解できず、CustomArgumentResolverは次のようになります。それのポイントは何ですか?

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;
        }
    }
}
4

2 に答える 2

3

@GaryFの回答に追加し、いくつかのポイントを明確にするために、Spring 2.5は、Spring2.0の古いインターフェイススタイルのコントローラーに代わる注釈付きコントローラーを導入しました。これらの新しいコントローラーには、固定パラメーターのないメソッドがあります。このメソッドは、ジョブを実行するために必要なパラメーターを宣言するだけで、それ以上のものはありません。

たとえば、コントローラーメソッドがその仕事をするために1つのことを必要としたとしましょう。それは、データベースからのオブジェクトのIDを含む要求パラメーターです。AbstractController.handleRequestInternal()Spring 2.0では、次のようなものを実装する必要があります。

protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
   String id = request.getParameter("id");
   MyThing obj = getObjById(id);
   //... do stuff and return ModelAndView
}

Spring 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いるapp-contextに登録できます。MyThingSpringはそのリゾルバーを呼び出し、その結果をコントローラーメソッドに渡します。

カスタムリゾルバは一般的には使用されませんが、適切な状況で非常に便利です。

質問の例ではCustomArgumentResolver、例のカスタムRequestAttributeクラスを解決するために使用しています。リゾルバーはリクエスト属性を引き出してRequestAttributeオブジェクトにバインドし、コントローラーメソッドパラメーターとして宣言できるようにします。

于 2011-03-20T22:13:06.517 に答える
1

WebArgumentResolversは、MVCマップメソッドのパラメーターをどのように解決するかを指定する方法です。カスタムオブジェクトをMVCマップメソッドのパラメーターとして使用する場合、Springは独自の方法でそれをどのように理解するかを理解しようとします。通常、これはバインディングによって発生します。ここで、送信する一部のhttpパラメーターはオブジェクトのフィールドと一致し、Springはそれらを一致させて新しいオブジェクトを作成します。

送信されたパラメーターがメソッドパラメーターと非常にうまく一致しない状況が発生した場合は、WebArgumentResolversがギャップを埋めるためにあります。カスタムロジックを提供するため、Springはそれを把握する必要がありません。

あなたの例では、paramは一致させるべきそのようなパラメータの1つです。このカスタムコードは、最初にパラメーターに@RequestAttributeアノテーションが付いているかどうかを確認します。含まれている場合、カスタムコードはそのオブジェクトから値を取得し、それをhttpリクエストの属性として検索して返します。そのアノテーションがない場合、メソッドはUNRESOLVED値を返します。これは、このWebArgumentResolverがこの特定のパラメーターについて何も知らないため、Springが別のメソッド(バインディングなど)を試行する必要があることを示しています。

于 2011-03-20T21:32:33.680 に答える