SWS-563 - Provide support for Apache HttpClient 4.0
This commit is contained in:
@@ -136,6 +136,11 @@
|
||||
<artifactId>mail</artifactId>
|
||||
</dependency>
|
||||
<!-- Transport dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -42,7 +42,9 @@ import org.apache.commons.httpclient.methods.PostMethod;
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
* @deprecated In favor of {@link HttpComponentsConnection}
|
||||
*/
|
||||
@Deprecated
|
||||
public class CommonsHttpConnection extends AbstractHttpSenderConnection {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -51,7 +51,9 @@ import org.apache.commons.httpclient.methods.PostMethod;
|
||||
* @see HttpClient
|
||||
* @see #setCredentials(Credentials)
|
||||
* @since 1.0.0
|
||||
* @deprecated In favor of {@link HttpComponentsMessageSender}
|
||||
*/
|
||||
@Deprecated
|
||||
public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSender
|
||||
implements InitializingBean, DisposableBean {
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2005-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.transport.http;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
/**
|
||||
* Implementation of {@link WebServiceConnection} that is based on Apache HttpClient. Exposes a {@link HttpPost} and
|
||||
* {@link HttpResponse}.
|
||||
*
|
||||
* @author Alan Stewart
|
||||
* @author Barry Pitman
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class HttpComponentsConnection extends AbstractHttpSenderConnection {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
private final HttpPost httpPost;
|
||||
|
||||
private HttpResponse httpResponse;
|
||||
|
||||
private ByteArrayOutputStream requestBuffer;
|
||||
|
||||
protected HttpComponentsConnection(HttpClient httpClient, HttpPost httpPost) {
|
||||
Assert.notNull(httpClient, "httpClient must not be null");
|
||||
Assert.notNull(httpPost, "httpPost must not be null");
|
||||
this.httpClient = httpClient;
|
||||
this.httpPost = httpPost;
|
||||
}
|
||||
|
||||
public HttpPost getHttpPost() {
|
||||
return httpPost;
|
||||
}
|
||||
|
||||
public HttpResponse getHttpResponse() {
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() throws IOException {
|
||||
if (httpResponse != null && httpResponse.getEntity() != null) {
|
||||
EntityUtils.consume(httpResponse.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* URI
|
||||
*/
|
||||
public URI getUri() throws URISyntaxException {
|
||||
return new URI(httpPost.getURI().toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* Sending request
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
|
||||
requestBuffer = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addRequestHeader(String name, String value) throws IOException {
|
||||
httpPost.addHeader(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OutputStream getRequestOutputStream() throws IOException {
|
||||
return requestBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
|
||||
httpPost.setEntity(new ByteArrayEntity(requestBuffer.toByteArray()));
|
||||
requestBuffer = null;
|
||||
httpResponse = httpClient.execute(httpPost);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receiving response
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected int getResponseCode() throws IOException {
|
||||
return httpResponse.getStatusLine().getStatusCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseMessage() throws IOException {
|
||||
return httpResponse.getStatusLine().getReasonPhrase();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getResponseContentLength() throws IOException {
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
if (entity != null) {
|
||||
return entity.getContentLength();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getRawResponseInputStream() throws IOException {
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
if (entity != null) {
|
||||
return entity.getContent();
|
||||
}
|
||||
throw new IllegalStateException("Response has no enclosing response entity, cannot create input stream");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<String> getResponseHeaderNames() throws IOException {
|
||||
Header[] headers = httpResponse.getAllHeaders();
|
||||
String[] names = new String[headers.length];
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
names[i] = headers[i].getName();
|
||||
}
|
||||
return Arrays.asList(names).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<String> getResponseHeaders(String name) throws IOException {
|
||||
Header[] headers = httpResponse.getHeaders(name);
|
||||
String[] values = new String[headers.length];
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
values[i] = headers[i].getValue();
|
||||
}
|
||||
return Arrays.asList(values).iterator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright 2005-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpRequestInterceptor;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.conn.routing.HttpRoute;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.impl.conn.SingleClientConnManager;
|
||||
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
|
||||
import org.apache.http.params.HttpConnectionParams;
|
||||
import org.apache.http.protocol.BasicHttpProcessor;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
* {@code WebServiceMessageSender} implementation that uses <a href="http://hc.apache.org/httpcomponents-client">Apache
|
||||
* HttpClient</a> to execute POST requests.
|
||||
* <p/>
|
||||
* Allows to use a pre-configured HttpClient instance, potentially with authentication, HTTP connection pooling, etc.
|
||||
* Authentication can also be set by injecting a {@link Credentials} instance (such as the {@link
|
||||
* UsernamePasswordCredentials}).
|
||||
*
|
||||
* @author Alan Stewart
|
||||
* @author Barry Pitman
|
||||
* @author Arjen Poutsma
|
||||
* @see HttpClient
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class HttpComponentsMessageSender extends AbstractHttpWebServiceMessageSender
|
||||
implements InitializingBean, DisposableBean {
|
||||
|
||||
private static final int DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS = (60 * 1000);
|
||||
|
||||
private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);
|
||||
|
||||
private HttpClient httpClient;
|
||||
|
||||
private Credentials credentials;
|
||||
|
||||
private AuthScope authScope = AuthScope.ANY;
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code HttpClientMessageSender} with a default {@link HttpClient} that uses a
|
||||
* default {@link SingleClientConnManager}.
|
||||
*/
|
||||
public HttpComponentsMessageSender() {
|
||||
httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager()) {
|
||||
@Override
|
||||
protected BasicHttpProcessor createHttpProcessor() {
|
||||
BasicHttpProcessor processor = super.createHttpProcessor();
|
||||
processor.addInterceptor(new ProtocolExceptionOverrideInterceptor(), 0);
|
||||
return processor;
|
||||
}
|
||||
};
|
||||
setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS);
|
||||
setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the <code>HttpClientMessageSender</code> with the given {@link HttpClient} instance.
|
||||
*
|
||||
* @param httpClient the HttpClient instance to use for this sender
|
||||
*/
|
||||
public HttpComponentsMessageSender(HttpClient httpClient) {
|
||||
Assert.notNull(httpClient, "httpClient must not be null");
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the credentials to be used. If not set, no authentication is done.
|
||||
*
|
||||
* @see UsernamePasswordCredentials
|
||||
* @see org.apache.http.auth.NTCredentials
|
||||
*/
|
||||
public void setCredentials(Credentials credentials) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>HttpClient</code> used by this message sender.
|
||||
*/
|
||||
public HttpClient getHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code HttpClient} used by this message sender.
|
||||
*/
|
||||
public void setHttpClient(HttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timeout until a connection is established. A value of 0 means <em>never</em> timeout.
|
||||
*
|
||||
* @param timeout the timeout value in milliseconds
|
||||
* @see org.apache.http.params.HttpConnectionParams#setConnectionTimeout(org.apache.http.params.HttpParams, int)
|
||||
*/
|
||||
public void setConnectionTimeout(int timeout) {
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("timeout must be a non-negative value");
|
||||
}
|
||||
HttpConnectionParams.setConnectionTimeout(getHttpClient().getParams(), timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the socket read timeout for the underlying HttpClient. A value of 0 means <em>never</em> timeout.
|
||||
*
|
||||
* @param timeout the timeout value in milliseconds
|
||||
* @see org.apache.http.params.HttpConnectionParams#setSoTimeout(org.apache.http.params.HttpParams, int)
|
||||
*/
|
||||
public void setReadTimeout(int timeout) {
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("timeout must be a non-negative value");
|
||||
}
|
||||
HttpConnectionParams.setSoTimeout(getHttpClient().getParams(), timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of connections allowed for the underlying HttpClient.
|
||||
*
|
||||
* @param maxTotalConnections the maximum number of connections allowed
|
||||
* @see ThreadSafeClientConnManager#setMaxTotal(int)
|
||||
*/
|
||||
public void setMaxTotalConnections(int maxTotalConnections) {
|
||||
if (maxTotalConnections <= 0) {
|
||||
throw new IllegalArgumentException("maxTotalConnections must be a positive value");
|
||||
}
|
||||
ClientConnectionManager connectionManager = getHttpClient().getConnectionManager();
|
||||
if (!(connectionManager instanceof ThreadSafeClientConnManager)) {
|
||||
throw new IllegalArgumentException("maxTotalConnections is not supported on " +
|
||||
connectionManager.getClass().getName() + ". Use " + ThreadSafeClientConnManager.class.getName() +
|
||||
" instead");
|
||||
}
|
||||
((ThreadSafeClientConnManager) connectionManager).setMaxTotal(maxTotalConnections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of connections per host for the underlying HttpClient. The maximum number of connections
|
||||
* per host can be set in a form accepted by the {@code java.util.Properties} class, like as follows:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* https://www.example.com=1
|
||||
* http://www.example.com:8080=7
|
||||
* http://www.springframework.org=10
|
||||
* </pre>
|
||||
* <p/>
|
||||
* The host can be specified as a URI (with scheme and port).
|
||||
*
|
||||
* @param maxConnectionsPerHost a properties object specifying the maximum number of connection
|
||||
* @see org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager#setMaxForRoute(org.apache.http.conn.routing.HttpRoute,
|
||||
* int)
|
||||
*/
|
||||
public void setMaxConnectionsPerHost(Map<String, String> maxConnectionsPerHost) throws URISyntaxException {
|
||||
ClientConnectionManager connectionManager = getHttpClient().getConnectionManager();
|
||||
if (!(connectionManager instanceof ThreadSafeClientConnManager)) {
|
||||
throw new IllegalArgumentException("maxConnectionsPerHost is not supported on " +
|
||||
connectionManager.getClass().getName() + ". Use " + ThreadSafeClientConnManager.class.getName() +
|
||||
" instead");
|
||||
}
|
||||
|
||||
for (Object o : maxConnectionsPerHost.keySet()) {
|
||||
String host = (String) o;
|
||||
URI uri = new URI(host);
|
||||
HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
|
||||
int maxHostConnections = Integer.parseInt(maxConnectionsPerHost.get(host));
|
||||
((ThreadSafeClientConnManager) connectionManager)
|
||||
.setMaxForRoute(new HttpRoute(httpHost), maxHostConnections);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication scope to be used. Only used when the <code>credentials</code> property has been set.
|
||||
* <p/>
|
||||
* By default, the {@link AuthScope#ANY} is used.
|
||||
*
|
||||
* @see #setCredentials(Credentials)
|
||||
*/
|
||||
public void setAuthScope(AuthScope authScope) {
|
||||
this.authScope = authScope;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (credentials != null && getHttpClient() instanceof DefaultHttpClient) {
|
||||
((DefaultHttpClient) getHttpClient()).getCredentialsProvider().setCredentials(authScope, credentials);
|
||||
}
|
||||
}
|
||||
|
||||
public WebServiceConnection createConnection(URI uri) throws IOException {
|
||||
HttpPost httpPost = new HttpPost(uri);
|
||||
if (isAcceptGzipEncoding()) {
|
||||
httpPost.addHeader(HttpTransportConstants.HEADER_ACCEPT_ENCODING,
|
||||
HttpTransportConstants.CONTENT_ENCODING_GZIP);
|
||||
}
|
||||
return new HttpComponentsConnection(getHttpClient(), httpPost);
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
getHttpClient().getConnectionManager().shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* HttpClient {@link org.apache.http.HttpRequestInterceptor} implementation that removes {@code Content-Length} and
|
||||
* {@code Transfer-Encoding} headers from the request. Necessary, because SAAJ and other SOAP implementations set these
|
||||
* headers themselves, and HttpClient throws an exception if they have been set.
|
||||
*/
|
||||
private static class ProtocolExceptionOverrideInterceptor implements HttpRequestInterceptor {
|
||||
|
||||
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
|
||||
if (request instanceof HttpEntityEnclosingRequest) {
|
||||
if (request.containsHeader(HTTP.TRANSFER_ENCODING)) {
|
||||
request.removeHeaders(HTTP.TRANSFER_ENCODING);
|
||||
}
|
||||
if (request.containsHeader(HTTP.CONTENT_LEN)) {
|
||||
request.removeHeaders(HTTP.CONTENT_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2005-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessage;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.ws.transport.support.FreePortScanner;
|
||||
|
||||
import org.apache.commons.httpclient.URIException;
|
||||
import org.junit.Test;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.Context;
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
|
||||
public class HttpComponentsMessageSenderIntegrationTest extends AbstractHttpWebServiceMessageSenderIntegrationTestCase {
|
||||
|
||||
@Override
|
||||
protected AbstractHttpWebServiceMessageSender createMessageSender() {
|
||||
return new HttpComponentsMessageSender();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxConnections() throws URISyntaxException, URIException {
|
||||
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
|
||||
messageSender.setMaxTotalConnections(2);
|
||||
Map<String, String> maxConnectionsPerHost = new HashMap<String, String>();
|
||||
maxConnectionsPerHost.put("https://www.example.com", "1");
|
||||
maxConnectionsPerHost.put("http://www.example.com:8080", "7");
|
||||
maxConnectionsPerHost.put("http://www.springframework.org", "10");
|
||||
messageSender.setMaxConnectionsPerHost(maxConnectionsPerHost);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextClose() throws Exception {
|
||||
MessageFactory messageFactory = MessageFactory.newInstance();
|
||||
int port = FreePortScanner.getFreePort();
|
||||
Server jettyServer = new Server(port);
|
||||
Context jettyContext = new Context(jettyServer, "/");
|
||||
jettyContext.addServlet(new ServletHolder(new EchoServlet()), "/");
|
||||
jettyServer.start();
|
||||
WebServiceConnection connection = null;
|
||||
try {
|
||||
|
||||
StaticApplicationContext appContext = new StaticApplicationContext();
|
||||
appContext.registerSingleton("messageSender", HttpComponentsMessageSender.class);
|
||||
appContext.refresh();
|
||||
|
||||
HttpComponentsMessageSender messageSender = appContext
|
||||
.getBean("messageSender", HttpComponentsMessageSender.class);
|
||||
connection = messageSender.createConnection(new URI("http://localhost:" + port));
|
||||
|
||||
connection.send(new SaajSoapMessage(messageFactory.createMessage()));
|
||||
connection.receive(new SaajSoapMessageFactory(messageFactory));
|
||||
|
||||
appContext.close();
|
||||
}
|
||||
finally {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (jettyServer.isRunning()) {
|
||||
jettyServer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class EchoServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
response.setContentType("text/xml");
|
||||
FileCopyUtils.copy(request.getInputStream(), response.getOutputStream());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -630,6 +630,11 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Transport dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user