1---2title: 'Java SOAP Web Services'3date: '2009-09-30'4published_at: '2009-09-30T12:47:00.012+10:00'5tags: ['java', 'jax-ws', 'programming', 'soap']6author: 'Gavin Jackson'7excerpt: 'Recently I was required to call some remote services (written in Microsoft.net) using SOAP from Java. There is a fair amount going on in the Java Web Services space (and an amazing number of acronyms...'8updated_at: '2009-09-30T15:10:03.422+10:00'9legacy_url: 'http://www.gavinj.net/2009/09/java-soap-web-services.html'10---1112Recently I was required to call some remote services (written in Microsoft.net) using SOAP from Java. There is a fair amount going on in the Java Web Services space (and an amazing number of acronyms).1314The three primary web service implementations for the Java platform consist of:1516- Apache Axis17- Sun JAX-WS and18- Codehaus CXF (previously known as Crossfire)1920I decided to use JAX-WS, which is the Sun reference implementation (which now ships standard with JDK6. For this example I'm only interested in talking to an existing web service (not creating my own), the web service in question has a published WSDL file (an xml interface specification).2122The first step was to generate the java stubs from the external WSDL file. This is done using the "wsimport" command. The generated files are then used by your (client) code to marshal, transmit, receive and unmarshal the SOAP calls.2324I was having a lot of trouble figuring out how to add data to the SOAP headers (in this case authentication details). After a day of banging my head against a brick wall I stumbled across the "-XadditionalHeaders" option.2526This really saved me - and I sincerely hope that this helps others out there!2728So this was the command I used to generate the web service client java code:29```30wsimport -p au.net.lesmills.zenkai.education.generated -s ~/work/zenkai/trunk/zenkai/BizEducation/src/ https://servicestest.lesmills.com:444/programkitcodes.asmx?WSDL -httpproxy:proxy:8080 -extension -XadditionalHeaders31```32I then wrote the following test client to call the validate method via SOAP:3334```35package au.net.lesmills.zenkai.education.test;3637import javax.xml.bind.JAXBException;38import javax.xml.ws.Holder;39import au.net.lesmills.zenkai.education.generated.*;40import com.sun.xml.internal.bind.api.JAXBRIContext;4142public class ProgramKitCodesTest{4344 public static void main(String args[]) throws JAXBException{4546 System.setProperty("https.proxyHost", "proxy.lesmills.net.au");47 System.setProperty("https.proxyPort", "8080");4849 System.out.println("Started");5051 ProgramKitCodes pkc = new ProgramKitCodes();52 ProgramKitCodesSoap pkcs = pkc.getProgramKitCodesSoap();5354 String username = "USERNAME";55 String password = "PASSWORD";5657 ObjectFactory of = new ObjectFactory();5859 AuthenticationHeader ah = of.createAuthenticationHeader();60 JAXBRIContext jbc = (JAXBRIContext) JAXBRIContext.newInstance("au.net.lesmills.zenkai.education.generated");61 ah.setUsername(username);62 ah.setPassword(password);6364 Holder h = new Holder(ah);6566 String kitCode = "KA35-LN0V-KG8B-0109-RPM42";67 ValidateResult result = pkcs.validate(kitCode, h);68 System.out.println("Completed - result is :" +69 result.getProgram() + " " +70 result.getQuarter() + " " +71 result.getReleaseNo());7273 }7475}76```7778Note how ProgramKitCodes is generated from the wsdl file - this provides an interface to all of the remote methods. The AuthenticationHeader JAXB object is part of the SOAP header specification (defined in the WSDL).7980Also, note how the above code uses a proxy server to talk to the external web services server (via ssl). No real magic here, you can use this technique in any java application.8182Although you won't be able to compile and test against the above SOAP implementation, I hope that this helps you get the ball rolling.838485