1

タイプのリクエストを消費するWebサービスに取り組んでいます application/x-www-form-urlencoded。このようなリクエスト本文の例を次に示します。

loginId=tester&action=add&requestId=987654321&data=somedata

要求はSHA1withRSAクライアントによって (で) 署名され、署名は HTTP ヘッダーとして送信されます。

問題は、次のように、常にパラメーターを異なる順序で取得することです。

action=add&loginId=tester&requestId=987654321&data=somedata

そのため、署名の検証は常に失敗します。

興味深いことに、これは が の場合にのみ発生しContent-Typeapplication/x-www-form-urlencodedを に切り替えるContent-Typetext/plain、すべてが完全に機能します。

さまざまな種類のクライアントを使用しました (TCP モニターを使用してトラフィックを監視したこともありました) が、問題の原因がクライアント アプリではないことは確かです。

以下は、カスタム メッセージ コンバーターの一部です (着信要求をコンソールに直接出力していることに注意してください)。

@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException,
        HttpMessageNotReadableException {

    log.debug("> readInternal - message to Object");
    InputStream inputStream = inputMessage.getBody();
    byte[] bytes = IOUtils.toByteArray(inputStream);
    String body = new String(bytes, charset);

    log.debug("Body: {}", body);
}

そして私のSpring MVC構成:

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <array>
            <bean class="converter.NvpHttpMessageConverter">
                <property name="charset" value="UTF-8" />
                <property name="nvpConverter" ref="nvpConverter" />
            </bean>
        </array>
    </property>

</bean>

Spring は何らかの形でコンテンツ タイプが であることを検出し、application/x-www-form-urlencoded何らかの前処理を使用していると思います。私の仮定は正しいですか?これをオフにすることはできますか?

Tomcat 7 を使用しています。

4

2 に答える 2

0

これが私が問題を解決した方法です:

AnnotationMethodHandlerAdapterを拡張し、 AnnotationMethodHandlerAdapter#createHttpInputMessageをオーバーライドしました

public class MyCustomAnnotationMethodHandlerAdapter extends AnnotationMethodHandlerAdapter {

    @Override
    protected HttpInputMessage createHttpInputMessage(HttpServletRequest servletRequest) throws Exception {
        return new ServletServerHttpRequest(servletRequest) {

            @Override
            public InputStream getBody() throws IOException {
                return getServletRequest().getInputStream();
            }
        };
    }
}

次に、元の AnnotationMethodHandlerAdapter の代わりにカスタム AnnotationMethodHandlerAdapter を登録する必要があります。

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

<bean class="webservice.handler.MyCustomAnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <array>
            <bean class="converter.NvpHttpMessageConverter">
                <property name="charset" value="UTF-8" />
                <property name="nvpConverter" ref="nvpConverter" />
            </bean>
        </array>
    </property>

</bean>
于 2013-08-26T15:00:23.083 に答える