Search code examples
javaspring-web

Send an HTTP request through a specific network interface using Spring RestTemplate


I am using Spring RestTemplate and I need to force my client to send an HTTP request through a specific network interface.

I already found a solution using java socket:

NetworkInterface nif = NetworkInterface.getByName("wlan0");
Enumeration<InetAddress> nifAddresses = nif.getInetAddresses();
Socket s = new Socket();
s.bind(new InetSocketAddress(nifAddresses.nextElement(), 0));
s.connect(new InetSocketAddress(host, port));
// Instantiates a new PrintWriter passing in the sockets output stream
PrintWriter wtr = new PrintWriter(s.getOutputStream());
// Prints the request string to the output stream
wtr.println("GET "+path+" HTTP/1.1");
wtr.println("Host: "+host);
wtr.println("");
wtr.flush();
BufferedReader br = new BufferedReader(new 
InputStreamReader(s.getInputStream()));
String content = "";
while ((content=br.readLine()) != null) 
     {
         System.out.println(content);       
     }

is there any way to reproduce this solution using Spring RestTemplate?


Solution

  • you need to configure the http client which is used by resttemplate

    private ClientHttpRequestFactory getClientHttpRequestFactory() {
    NetworkInterface nif = NetworkInterface.getByName("sup0");
    Enumeration<InetAddress> nifAddresses = nif.getInetAddresses();
    RequestConfig config = RequestConfig.custom()
            .setLocalAddress(nifAddresses.nextElement()).build();
    
    CloseableHttpClient client = HttpClientBuilder
      .create()
      .setDefaultRequestConfig(config)
      .build();
    return new HttpComponentsClientHttpRequestFactory(client);
    

    }

    and then...

    RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
    

    binding network interface to Apache httpclient