Saturday, April 2, 2011

Using web service client behind a http proxy server

Web service is a popular medium of communication between devices over a network. But most of the time you find yourself behind a http proxy server to connect to the network. Proxy servers are often found in company networks. The main reasons for their introduction are - security, resource caching, auditing etc. But ultimately they block unauthorized access to internet from the inside network. This leads to the problem we are going to solve now.

We are going to use w3schools temperature converter service (WSDL download) for testing. Make sure you are actually running this code behind a http proxy server. You also need to know the proxy server's host name and the port no.  I'll assume that you can generate the client stubs using JAX-WS (or some other tool). I have used wsconsume tool to generated my stubs.

In my case, com.w3schools.TempConvert is the implementation class and com.w3schools.TempConvertSoap is the interface. Then I have a com.w3schools.client.WSClient class which is the actual client.

The trick here is to initialize a new instance of java.net.ProxySelector class in WSClient code with your proxy settings. To achieve that you need to write a class which extends java.net.ProxySelector. See below -




package com.w3schools.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.*;
import java.util.*;

public class MyProxySelector extends ProxySelector {

    @Override
    public List select(URI uri) 
    {
        // Setting up a new ProxySelector implementation
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("mywebproxy.com", 8080));
        ArrayList list = new ArrayList();
        list.add(proxy);
        return list;
    }

    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
        System.err.println("Connection to " + uri + " failed.");
    }
}


With MyProxySelector class being ready we can set this default proxy in the WSClient code. Like this -


package com.w3schools.client;

import java.net.ProxySelector;

import com.w3schools.TempConvert;
import com.w3schools.TempConvertSoap;

public class WSClient {
 public static void main(String[] args) {
  ProxySelector.setDefault(new MyProxySelector()); 
  TempConvertSoap service = new TempConvert().getTempConvertSoap();
  String cel = service.fahrenheitToCelsius("40");
  String fah = service.celsiusToFahrenheit("100");
  System.out.println(cel + "  " + fah);
 }
}


Now you can invoke the WSClient to use w3school web service even from behind a proxy.