diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index d41a0694998..cf864fcfc07 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -18,7 +18,9 @@ package org.springframework.http.client; import java.io.IOException; import java.net.HttpURLConnection; +import java.net.Proxy; import java.net.URI; +import java.net.URL; import java.net.URLConnection; import org.springframework.http.HttpMethod; @@ -34,17 +36,40 @@ import org.springframework.util.Assert; */ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory { + private Proxy proxy; + + /** + * Sets the {@link Proxy} to use for this request factory. + */ + public void setProxy(Proxy proxy) { + this.proxy = proxy; + } + public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { - URLConnection urlConnection = uri.toURL().openConnection(); - Assert.isInstanceOf(HttpURLConnection.class, urlConnection); - HttpURLConnection connection = (HttpURLConnection) urlConnection; + HttpURLConnection connection = openConnection(uri.toURL(), proxy); prepareConnection(connection, httpMethod.name()); return new SimpleClientHttpRequest(connection); } /** - * Template method for preparing the given {@link HttpURLConnection}.

The default implementation prepares the - * connection for input and output, and sets the HTTP method. + * Opens and returns a connection to the given URL. + *

The default implementation uses the given {@linkplain #setProxy(java.net.Proxy) proxy} - if any - to open a + * connection. + * + * @param url the URL to open a connection to + * @param proxy the proxy to use, may be {@code null} + * @return the opened connection + * @throws IOException in case of I/O errors + */ + protected HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException { + URLConnection urlConnection = proxy != null ? url.openConnection(proxy) : url.openConnection(); + Assert.isInstanceOf(HttpURLConnection.class, urlConnection); + return (HttpURLConnection) urlConnection; + } + + /** + * Template method for preparing the given {@link HttpURLConnection}. + *

The default implementation prepares the connection for input and output, and sets the HTTP method. * * @param connection the connection to prepare * @param httpMethod the HTTP request method ({@code GET}, {@code POST}, etc.) diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/support/ProxyFactoryBean.java b/org.springframework.web/src/main/java/org/springframework/http/client/support/ProxyFactoryBean.java new file mode 100644 index 00000000000..0ba4e815416 --- /dev/null +++ b/org.springframework.web/src/main/java/org/springframework/http/client/support/ProxyFactoryBean.java @@ -0,0 +1,87 @@ +/* + * Copyright 2002-2010 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.http.client.support; + +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.SocketAddress; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; + +/** + * {@link FactoryBean} that creates a {@link Proxy java.net.Proxy}. + * + * @author Arjen Poutsma + * @since 3.0.4 + * @see FactoryBean + * @see Proxy + */ +public class ProxyFactoryBean implements FactoryBean, InitializingBean { + + private Proxy.Type type = Proxy.Type.HTTP; + + private String hostname; + + private int port = -1; + + private Proxy proxy; + + /** + * Sets the proxy type. Defaults to {@link Proxy.Type#HTTP}. + */ + public void setType(Proxy.Type type) { + this.type = type; + } + + /** + * Sets the proxy host name. + */ + public void setHostname(String hostname) { + this.hostname = hostname; + } + + /** + * Sets the proxy port. + */ + public void setPort(int port) { + this.port = port; + } + + public void afterPropertiesSet() throws IllegalArgumentException { + Assert.notNull(type, "'type' must not be null"); + Assert.hasLength(hostname, "'hostname' must not be empty"); + Assert.isTrue(port >= 0 && port <= 65535, "'port' out of range: " + port); + + SocketAddress socketAddress = new InetSocketAddress(hostname, port); + this.proxy = new Proxy(type, socketAddress); + + } + + public Proxy getObject() { + return proxy; + } + + public Class getObjectType() { + return Proxy.class; + } + + public boolean isSingleton() { + return true; + } +} diff --git a/org.springframework.web/src/test/java/org/springframework/http/client/support/ProxyFactoryBeanTest.java b/org.springframework.web/src/test/java/org/springframework/http/client/support/ProxyFactoryBeanTest.java new file mode 100644 index 00000000000..1bb2e0e5242 --- /dev/null +++ b/org.springframework.web/src/test/java/org/springframework/http/client/support/ProxyFactoryBeanTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2002-2010 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.http.client.support; + +import java.net.InetSocketAddress; +import java.net.Proxy; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Arjen Poutsma + */ +public class ProxyFactoryBeanTest { + + ProxyFactoryBean factoryBean; + + @Before + public void setUp() { + factoryBean = new ProxyFactoryBean(); + } + + @Test(expected = IllegalArgumentException.class) + public void noType() { + factoryBean.setType(null); + factoryBean.afterPropertiesSet(); + } + + @Test(expected = IllegalArgumentException.class) + public void noHostname() { + factoryBean.setHostname(""); + factoryBean.afterPropertiesSet(); + } + + @Test(expected = IllegalArgumentException.class) + public void noPort() { + factoryBean.setHostname("example.com"); + factoryBean.afterPropertiesSet(); + } + + @Test + public void normal() { + Proxy.Type type = Proxy.Type.HTTP; + factoryBean.setType(type); + String hostname = "example.com"; + factoryBean.setHostname(hostname); + int port = 8080; + factoryBean.setPort(port); + factoryBean.afterPropertiesSet(); + + Proxy result = factoryBean.getObject(); + + assertEquals(type, result.type()); + InetSocketAddress address = (InetSocketAddress) result.address(); + assertEquals(hostname, address.getHostName()); + assertEquals(port, address.getPort()); + } + +}