我们正在努力配置我们的Web应用程序,以便能够通过Spring WS连接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 XML配置,因为有些setter没有使用Spring期望的格式。 (HttpState.setCredentials(...)有两个参数)。该配置已从该公司的其他一些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对象上设置凭据时,它们只是被忽略了......
答案 0 :(得分:2)
使用构造函数覆盖HttpClient,该构造函数接受参数并使用constructor-args连接Spring
public MyHttpClient(HttpClientParams params, UsernamePasswordCredentials usernamePasswordCredentials) {
super(params);
getState().setCredentials(AuthScope.ANY, usernamePasswordCredentials);
}
答案 1 :(得分:1)
你如何区分这些:
<constructor-arg value="john"/>
<constructor-arg value="secret"/>
尝试将其替换为:
<property name="userName" value="john" />
<property name="password" value="secret" />
希望它有所帮助。
答案 2 :(得分:0)
如果您使用的是类似于示例的defaultHttpClient,请在HTTPMessageSender上使用afterPropertiesSet方法,并通过正确应用凭据来解决问题
答案 3 :(得分: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" />
这是我们启用cridentials的选项。我们设置这样的凭据时出现问题。 如果我们发送消息的服务器(有Axis impl)没有用户名密码凭据,我们会收到“未经授权”的异常。因为,当我们跟踪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;
}