3

Spring WS を介して Web サービスに接続できるように Web アプリを構成するのに苦労しています。クライアント側 Spring-WS のドキュメントの例を使用しようとしましたが、最終的に WebServiceTransportException が発生します。XML 構成は次のようになります。

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <constructor-arg ref="messageFactory"/>
    <property name="messageSender">
        <bean class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
            <property name="credentials">
                <bean class="org.apache.commons.httpclient.UsernamePasswordCredentials">
                    <constructor-arg value="john"/>
                    <constructor-arg value="secret"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>

アプリケーションをプログラムで構成することはできましたが、一部のセッターが Spring が期待する形式を使用しなかったため、この構成を Spring XML 構成に「転送」することはできませんでした。(HttpState.setCredentials(...) は 2 つのパラメーターを取ります)。構成は、社内の他の Spring-WS クライアント コードから持ち上げられました。

これは機能する構成です。

 public List<String> getAll() {
    List<String> carTypes = new ArrayList<String>();

    try {
        Source source = new ResourceSource(request);
        JDOMResult result = new JDOMResult();


        SaajSoapMessageFactory soapMessageFactory = new SaajSoapMessageFactory(MessageFactory.newInstance());

        WebServiceTemplate template = new WebServiceTemplate(soapMessageFactory);

        HttpClientParams clientParams = new HttpClientParams();
        clientParams.setSoTimeout(60000);
        clientParams.setConnectionManagerTimeout(60000);
        clientParams.setAuthenticationPreemptive(true);

        HttpClient client = new HttpClient(clientParams);
        client.getState().setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials("username", "password"));

        CommonsHttpMessageSender messageSender = new CommonsHttpMessageSender(client);

        template.setMessageSender(messageSender);
        template.sendSourceAndReceiveToResult(SERVICE_URI,
                source, result);

        // Handle the XML

    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (SOAPException e) {
        throw new RuntimeException(e);
    }

    return carTypes;
}

私の問題を解決する方法を知っている人はいますか?私が目にしたすべてのチュートリアルには、最初の構成がリストされています。messageSender オブジェクトに資格情報を設定すると、それらは無視されるようです...

4

4 に答える 4

2

パラメータを取得し、constructor-argsを使用してSpringを介してワイヤリングするコンストラクタでHttpClientをオーバーライドします

public MyHttpClient(HttpClientParams params, UsernamePasswordCredentials usernamePasswordCredentials) {
        super(params);        
        getState().setCredentials(AuthScope.ANY, usernamePasswordCredentials);
    }
于 2009-12-16T16:04:01.147 に答える
1

これらをどのように区別しますか:

<constructor-arg value="john"/>
<constructor-arg value="secret"/>

これを次のように置き換えてみてください。

<property name="userName" value="john" />
<property name="password" value="secret" />

それが役に立てば幸い。

于 2008-09-29T19:10:13.887 に答える
0

例のように defaultHttpClient を使用している場合は、HTTPMessageSender で afterPropertiesSet メソッドを使用すると、資格情報を正しく適用することで問題を解決できます。

于 2013-05-01T19:41:15.080 に答える
0

最初は、プロジェクトで資格情報を次のように設定していました。

<bean id="authenticationEnabledCommonsHttpMessageSender" parent="commonsHttpMessageSender"
    p:credentials-ref="clientCredentials" lazy-init="true" />
<bean id="clientCredentials"
    class="org.apache.commons.httpclient.UsernamePasswordCredentials"
    c:userName="${clientCredentials.userName}"
    c:password="${clientCredentials.password}"
    lazy-init="true" />

これは、資格情報が有効なオプションです。そのような資格情報を設定しているときに問題が発生しました。メッセージを送信するサーバー (Axis impl を含む) がユーザー名とパスワードの資格情報を取得していない場合、"Unauthorized" 例外が発生します。TCPMon 経由でトレースすると、「username:password:」文字列が送信されていることがわかりました。ユーザー名とパスワードに値がないことがわかります。

その後、資格情報を次のように設定します。

public Message sendRequest(OutgoingRequest message, MessageHeaders headers,
                        EndpointInfoProvider endpointInfoProvider,
                        WebServiceMessageCallback requestCallback){
    Assert.notNull(endpointInfoProvider, "Destination provider is required!");
    final Credentials credentials = endpointInfoProvider.getCredentials();
    URI destinationUri = endpointInfoProvider.getDestination();
    for (WebServiceMessageSender messageSender : webServiceTemplate.getMessageSenders()) {
        if (messageSender instanceof CommonsHttpMessageSender) {
            HttpClient httpClient = ((CommonsHttpMessageSender) messageSender).getHttpClient();
            httpClient.getState().setCredentials(
                    new AuthScope(destinationUri.getHost(),
                            destinationUri.getPort(), AuthScope.ANY_REALM,
                            AuthScope.ANY_SCHEME), credentials
            );
            httpClient.getParams().setAuthenticationPreemptive(true);
            ((CommonsHttpMessageSender) messageSender)
                    .setConnectionTimeout(endpointInfoProvider
                            .getTimeOutDuration());
        }
    }

getCredentials メソッドは次のとおりです。

@Override
public Credentials getCredentials(){
    if (credentials != null) {
        return credentials;
    }
    String username = parameterService.usernameFor(getServiceName());
    String password = parameterService.passwordFor(getServiceName());
    if (username == null && password == null) {
        return null;
    }
    credentials = new UsernamePasswordCredentials(username, password);
    return credentials;
}
于 2014-09-04T08:55:24.047 に答える