pvillega’s posterous

pvillega’s posterous

Pere Villega  //  Born in Barcelona, living in Dublin, and tagged as geek since youth. Developer in the path to becoming a software architect. I swear this is not a proper blog :)

Feb 16 / 7:28am

Web services (JAX-WS)

This page contains a brief summary of Web services. It only gives basic information, for more details about life cycle and other functionalities check the EJB 3.0 reference or some book like EJB3 in Action.

Java gives support to several implementations of web services, as REST, XML-RPC or SOAP. Sadly JEE 5 doesn't require support for REST so it's covered by proprietary extensions, but it covers pretty well XML-RPC and specially SOAP using JAX-WS. In this section I won't discuss the particulars of web services like UDDI or WSDL. Suffice to say JAX-WS 2.0 is the API to use for managing web services and it provides compatibility with JEE 1.4 XML-RPC calls although it favours SOAP web services. This library allows you to use both POJOs or EJB as web services. Although each one has its advantages (like POJOs being able to run in tomcat while EJB aren't) the usage of EJB as web services is recommended as you obtain extra container functionalities like timers, transactions, security and more that plain POJOs lack.

An example of stateless Session bean being exposed as web service:

//We use annotations to generate our web service interface over a stateless bean
//WebService is the only required annotation and defines de urn
//SOAPBinding can be document (SOAP) or RPC (XML-RPC)

@WebService(targetNamespace ="urn:DemoWebService")
@SOAPBinding( style = SOAPBinding.Style.DOCUMENT)
@Stateless
public class WebServiceBean implements WebServiceLocal {

//these annotations allows us to control the names of the params and return value
//of the exposed method
@WebMethod
@WebResult (name = "webNumber")
public Long webMethod(@WebParam(name = "user") String user) {
return Long.MAX_VALUE;
}
}

The only required annotation is @WebService. Other annotation allows us to configure details like the binding (SOAP or RPC), which methods are exposed and the names of the parameters in the WSDL.

@WebService can be added to the bean or to one interface. If added to the interface all its methods will be exposed, while if we use it on the bean it will expose all the bean methods, unless we mark them explicitly with @WebMethod to identify the ones which should be exposed. @WebMethod can also be used to mark methods that must be hidden user the parameter "exclude" in the annotation.

@WebParam can be used to customize parameters (and @WebResult for the return value) of a method. It allows to change the exposed name and the mode (IN, OUT, INOUT) of each parameter along with other properties. There are some other annotations in the specification, like @OneWay, used to mark method with no output so they are optimized, or @HandlerChain to set up web service specific interceptors.

To consume those web services, you can use the @WebServiceRef annotation both in Java clients or EJB. In the latter case the annotation can be used to perform dependency injection.

Loading mentions Retweet

Filed under // ejb java jax-ws web service

Comments (0)

Feb 16 / 6:20am

Web service using SSL

Using web services with Javais really easy, that is until you start using SSL to secure them. In a recent application I was developing I needed to access a web service that used SSL from a JSE Wing client. The certificate was bought, server set up and when I connected...

  javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:

PKIX path building failed:

sun.security.provider.certpath.SunCertPathBuilderException:

unable to find valid certification path to requested target

Marvellous! After spending some time in Google I found the error was raised because the JVM was unable to recognize the certificate as a valid one. The only solution was to create a keystore where I would save the certificate for the application, which I achieved with the steps explained in this post. We will use the installcert code to generate the local keystore. We compile the code and then run:

  java InstallCert www.domain.com

first time it will show us one error (the mentioned SSLHandshakeException) and ask us if we want to add that certificate to the keystore. Once added we can run the program again to see that instead of the error it tells us the certificate has been recognised. Once done, copy the generated file (jssecacerts) to a folder of your application (I chose conf folder). Then add this line on your application:

  System.setProperty("javax.net.ssl.trustStore", "conf/jssecacerts");

this will register our keystore with the application and allow Java to acknowledge the certificate. This approach has one obvious inconvenient: if the certificate changes like it will when renewed, we will need to register it again in our local keystore, which is not ideal, but at least solves the issue temporally.

Loading mentions Retweet

Filed under // java ssl web service

Comments (0)

Jan 24 / 2:31pm

Testing WebServices

Hi there, long time no see ;) In my recent projects I've had some issues with web services and needed to debug the SOAP calls as the stack trace was not helping. Searching on a solution I found Axis has a nice proxy for web services, that lets you intercept the SOAP calls and see the output. You'll need the following jars:
  • axis-1.4.jar
  • axis-wsdl4j-1.5.1.jar
  • commons-loggin-1.1.1.jar
  • commons-discovery-20040218.194635.jar
and the code below:
 System.getProperties().setProperty("http.proxySet", "true");
 System.getProperties().setProperty("http.proxyHost", "127.0.0.1");
 System.getProperties().setProperty("http.proxyPort", "8080");

 /*specify wsdl*/
 String wsdlURL = "http://localhost/mantis/api/soap/mantisconnect.php?wsdl";
 /*specify name space*/
 String nmspace = "http://futureware.biz/mantisconnect";
 /*specify target service*/
 String srvname = "MantisConnect";
 /*specify target method*/
 String fncname = "mc_version";
 /*specify your query*/
 String query = "";

 /*defin serviceQN,portQN*/
 QName serviceQN = new QName(nmspace, srvname);
 QName portQN = new QName(nmspace, "MantisConnectPort");
 /*define service*/
 Service service = new Service(new URL(wsdlURL), serviceQN);
 /*execute soap*/
 Call call = (Call) service.createCall(portQN, fncname);
 //Pass params!
 //String result = (String)call.invoke(new Object[]{query});
 String result = (String) call.invoke(new Object[]{});
 System.out.println(result);

Then run the proxy program:
java -cp axis-1.4.jar org.apache.axis.utils.tcpmon
and set up a proxy on port 8080 to intercept calls. Customise the code (wsdl, namespace, etc), and run it. You'll see the input/output in your proxy.
Loading mentions Retweet

Filed under // java unit testing web service

Comments (0)