6

@RequestBodySpringのアノテーションとを使用して、リクエストのJSONPOSTデータをオブジェクトにマッピングしていますMappingJacksonHttpMessageConverterStringただし、その後、フォームのデータを読み取って、追加の認証を行いたいと思います。しかし、マーシャリングが行われたとき、InputStreaminHttpServletRequestは空です。メソッドからパラメーターを削除すると@RequestBody、POSTデータの読み取りはString期待どおりに機能します。

をあきらめて@RequestBodyバインディングを手動で行うことで妥協する必要がありますか、それともより洗練された解決策がありますか?

4

3 に答える 3

2

したがって、基本的にはリクエスト本文のハッシュを計算する必要があります。それを行うためのエレガントな方法は、デコレータをに適用することInputStreamです。

たとえば、ハンドラーメソッド内(この場合は使用できず、手動で@RequestBody作成する必要がありますHttpMessageConverter):

@RequestMapping(...)
public void handle(HttpServletRequest request) throws IOException {
    final HashingInputStreamDecorator d = 
        new HashingInputStreamDecorator(request.getInputStream(), secretKey);
    HttpServletRequest wrapper = new HttpServletRequestWrapper(request) {
        @Override
        public ServletInputStream getInputStream() throws IOException {
            return d;
        }
    };

    HttpMessageConverter conv = ...;
    Foo requestBody = (Foo) conv.read(Foo.class, new ServletServerHttpRequest(wrapper));
    String hash = d.getHash();

    ...
}

ここで、ハッシュはのオーバーライドされたreadメソッドで段階的に計算されますHashingInputStreamDecorator

デコレータを適用する@RequestBodyためにを作成する場合にも使用できます。Filterこの場合、デコレータは計算されたハッシュをリクエスト属性としてハンドラメソッドに渡すことができます。ただし、このフィルターを慎重にマップして、特定のハンドラーメソッドへのリクエストにのみ適用する必要があります。

于 2010-11-04T14:34:16.693 に答える
0

urlMapping Beanで、追加のインターセプターのリストを宣言できます。

  <bean id="urlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
      <list>
        <bean class="org.foo.MyAuthInterceptor"/>
      </list>
    </property>
  </bean>

これらのインターセプターはHttpServletRequestにアクセスできますが、ストリームから読み取る場合、パラメーターマッパーがそれを読み取ることができない可能性があります。

public class AuthInterceptor extends HandlerInterceptorAdapter {

  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    ...
  }

  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) {
    ...
  }
}
于 2010-11-04T13:24:16.230 に答える
0

これを正しく理解していれば、JAX-RSで使用される一般的な方法の1つ(バインディング要求に関してはSpring MVCにいくらか似ています)は、最初に中間のraw型(通常はbyte []ですが、Stringも機能します)に「バインド」することです。 、および基になるデータバインダー(Jackson)を使用して、そこからオブジェクトに手動でバインドします。データバインディングのエラー処理を完全にカスタマイズできるようにするために、これを行うことがよくあります。

于 2010-11-17T00:13:01.850 に答える