Como posso especificar o endereço local em um java.net.URLConnection?

Minha instância do Tomcat está ouvindo vários endereços IP, mas quero controlar qual endereço IP de origem é usado ao abrir uma URLConnection .

Como posso especificar isso?

Isso deve fazer o truque:

 URL url = new URL(yourUrlHere); Proxy proxy = new Proxy(Proxy.Type.DIRECT, new InetSocketAddress( InetAddress.getByAddress( new byte[]{your, ip, interface, here}), yourTcpPortHere)); URLConnection conn = url.openConnection(proxy); 

E você está feito. Não se esqueça de lidar bem com as exceções e, claro, alterar os valores para se adequar ao seu cenário.

Ah e eu omiti as instruções de importação

Usando o Apache commons HttpClient Eu também encontrei o seguinte para trabalhar (removido try / catch para maior clareza):

 HostConfiguration hostConfiguration = new HostConfiguration(); byte b[] = new byte[4]; b[0] = new Integer(192).byteValue(); b[1] = new Integer(168).byteValue(); b[2] = new Integer(1).byteValue(); b[3] = new Integer(11).byteValue(); hostConfiguration.setLocalAddress(InetAddress.getByAddress(b)); HttpClient client = new HttpClient(); client.setHostConfiguration(hostConfiguration); GetMethod method = new GetMethod("http://remoteserver/"); method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); int statusCode = client.executeMethod(method); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + method.getStatusLine()); } byte[] responseBody = method.getResponseBody(); System.out.println(new String(responseBody));"); 

No entanto, eu ainda me pergunto o que aconteceria se o gateway do IP estiver inativo (192.168.1.11 neste caso). O próximo gateway será tentado ou falhará?

A maneira óbvia de portabilidade seria definir um proxy em URL.openConnection. O proxy pode estar no host local, então você pode escrever um proxy muito simples que liga o endereço local do soquete do cliente.

Se você não puder modificar a origem na qual o URL está conectado, poderá replace o URLStreamHandler ao chamar o construtor de URL ou globalmente por meio de URL.setURLStreamHandlerFactory. O URLStreamHandler pode então delegar para o manipulador padrão http / https, modificando a chamada openConnection.

Um método mais extremo seria replace completamente o manipulador (talvez estendendo a implementação em seu JRE). Como alternativa, os clientes http alternativos (código-fonte aberto) estão disponíveis.

Configurando manualmente soquete funciona bem …

 private HttpsURLConnection openConnection(URL src, URL dest, SSLContext sslContext) throws IOException, ProtocolException { HttpsURLConnection connection = (HttpsURLConnection) dest.openConnection(); HttpsHostNameVerifier httpsHostNameVerifier = new HttpsHostNameVerifier(); connection.setHostnameVerifier(httpsHostNameVerifier); connection.setConnectTimeout(CONNECT_TIMEOUT); connection.setReadTimeout(READ_TIMEOUT); connection.setRequestMethod(POST_METHOD); connection.setRequestProperty(CONTENT_TYPE, SoapConstants.CONTENT_TYPE_HEADER); connection.setDoOutput(true); connection.setDoInput(true); connection.setSSLSocketFactory(sslContext.getSocketFactory()); if ( src!=null ) { InetAddress inetAddress = InetAddress.getByName(src.getHost()); int destPort = dest.getPort(); if ( destPort <=0 ) destPort=SERVER_HTTPS_PORT; int srcPort = src.getPort(); if ( srcPort <=0 ) srcPort=CLIENT_HTTPS_PORT; connectionSocket = connection.getSSLSocketFactory().createSocket(dest.getHost(), destPort, inetAddress, srcPort); } connection.connect(); return connection; }