Java Web Service Client – Proxy Configuration
I’ve spent the last few days integrating an application with the Experian bank account validation service, using Axis2 as the web service client. The client worked fine in our dev environment but couldnt connect when deployed in the customers corporate network.
The Axis client was throwing an UnknownHostException because it couldn’t resolve the service URL. Strangely though, on the same machine I was able to paste the URL into a browser and view the service WSDL. After some digging around I realised that all HTTP requests that go out to the public internet need to be routed through the corporate proxy server. I looked around and found a few different ways of doing this – I’ll document each approach and hopefully it’ll help out someone else.
Solution 1 – Set Proxy Details On Axis2 Web Service Stub
Axis provides a convenient way for you to set proxy configuration details if your web service request has to be routed through a proxy. The sample code below shows how this is done.
TokenServiceStub tokenService = new TokenServiceStub("https://secure.authenticator.uat.uk.experian.com/WASPAuthenticator/TokenService.asmx"); HttpTransportProperties.ProxyProperties proxyProperties = new HttpTransportProperties.ProxyProperties(); proxyProperties.setDomain("mydomain"); proxyProperties.setProxyName("184.108.40.206"); proxyProperties.setProxyPort(80); proxyProperties.setUserName("myusername"); proxyProperties.setPassWord("mypassword"); tokenService._getServiceClient().getOptions().setProperty(HTTPConstants.PROXY, proxyProperties);
We simply set the proxy details on a the HttpTransportProperties.ProxyProperties, which is then set on the ServiceClients Options.
When the service stub (TokenServiceStub) is used to call a service method the HTTP request will be routed through the proxy defined above. This approach is very straight forward but is specific to this particular service stub. The next solution is a little more generic and can be used to proxy all web service requests sent by your application.
Solution 2 – Set Proxy Details programmatically as Java System Properties
This approach allows your application to set proxy details as Java system properties. The advantage of this approach is that it will ensure that all HTTP requests generated by your application will be affected which is convenient if you have an application with multiple web service clients. Rather than set proxy properties on each Service stub you can simply set them once as system properties and these values will automatically be used by all web service clients in your application. The code below shows how you can set target proxy details as system properties.
System.setProperty("http.proxyHost", "192.155.1168.101"); System.setProperty("http.proxyPort", "80"); System.setProperty("https.proxyHost", "220.127.116.11"); System.setProperty("https.proxyPort", "81"); System.setProperty("http.nonProxyHosts","192.168.170.105|192.168.170.104");
If you need to support HTTPS proxying you can change http.proxyHost to https.proxyHost and http.proxyPort to https.proxyPort
By default these settings will ensure that all HTTP traffic is sent via the specified proxy. But what if you have exceptions to this rule? Luckily the nonProxyHosts setting allows you to specify one or more exceptions to the proxy rule. For example your application may connect to a number of internal and external services. You may only want to route the external service requests through the proxy and let internal requests go directly to their target URL. If this is the case you specify the hosts that you do not want to route through the proxy using nonProxyHosts. You can wildcard values using * and multiple entries are delimited by |.
Solution 3 – Set Proxy Details declaratively as JVM arguments
Another approach (this is the approach I went for) is to set the proxy values as JVM arguments. This means that your application code is free from having to set the proxy details programmatically. For a simple command line application you would set these values as follows.
java -Dhttp.proxyHost=18.104.22.168 -Dhttp.proxyPort=80 –jar StandaloneApp.jar
In most instances though your application will be deployed inside a servlet container like Tomcat. If this is the case you can add these values as JVM arguments that are read on server startup. In my case I had Tomcat set up as a windows service, so to add the proxy settings as JVM arguments I followed these steps.
- Go to $TOMCAT_HOME/bin
- Open Tomcat6W.exe and the following options will be displayed.
- Click on the Java tab
- Add your proxy settings to the existing list of JVM parameters as shown in the screenshot below.
If Tomcat is not running as a windows service you’ll need to add the start up parameters to Catalina.bat or Catalina.sh (depending on what platform you’re running Tomcat).