2008-07-21

Building JAX-RPC or JAX-WS webservices with Weblogic 10

Introduction

On Weblogic 10, you've got the choice to design your webservice following two norms :

Ø      JAX-RPC 1.1

Ø      JAX-WS (aka JAX-RPC 2.0)

We are going to study the way to design a simple webservice using standard annotations, and then to publish it as JAX-RPC or JAX-WS webservice.

And I will describe what are the main differences between them.

 

Designing the webservice

The webservice is an easy one : it's designed to receive a file. I like to use that subject because it's a functionality that is often needed.

import java.io.FileOutputStream;

import java.io.IOException;

import javax.jws.Oneway;

import javax.jws.WebService;

@WebService

public class PdfSaver {

      @Oneway

      public void savePdf (byte[] pdfFile) {

            FileOutputStream fos = null;

            try {

                  // Saving the file in "myDomain/pdf"

                  fos = new FileOutputStream("pdf/sample.pdf");

                  fos.write(pdfFile);

            } catch (IOException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

            } finally {

                  try {

                        fos.close();

                  } catch (IOException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                  }

            }

      }

}

Note : the annotation "@WebMethod" is useful when you have got several methods and you want only some of them to be published. By default, if you do not write it, all methods are exposed.

The annotation "@Oneway" is used when your webservice does not return any value.

 

Common configuration

In your build.xml file, you've got to declare the "jwsc" task like this :

<taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" />

<property name="dest.dir" value="${project}\src" />

Note : This class is in a jar called "wseeclient.jar " located in the directory

"BEA_HOME /wlsserver_10.0 / server / lib".

Be sure to have it referenced in your classpath, as well as the "weblogic.jar" file, located in the same directory.

 

Using JAX-RPC 1.1

Ant task looks like that :

<target name="build-webservice">

      <jwsc srcdir="src" destdir="${dest.dir}">

            <jws file="com/sample/ws/PdfSaver.java" type="JAXRPC" />

      </jwsc>

</target>

Note : the type "JAXRPC" is used by default. I'm only writing it down to be clearer.

Once published, check your webservice is of the correct type :

(Deployments > PdfSaverService > Configuration > General)

JAX-RPC

Using JAX-WSOneway"tation "exposed.ot

you want only some of them to be published.

The Ant task looks alike, but the type which has now been set to "JAXWS" :

<target name="build-webservice">

      <jwsc srcdir="src" destdir="${dest.dir}">

            <jws file="com/sample/ws/PdfSaver.java" type="JAXWS" />

      </jwsc>

</target>

Once published, check your webservice is of the correct type :

(Deployments > PdfSaverService > Configuration > General)

JAX-WS

Generating the client

Common configuration

<property name="dest.package" value="webservice.client.jaxws" />

<property name="dest.dir" value="${project}\src" />

<taskdef name="clientgen"    classname="weblogic.wsee.tools.anttasks.ClientGenTask" />

Note : This class is in a jar called "wseeclient.jar " located in the directory

"BEA_HOME /wlsserver_10.0 / server / lib".

Be sure to have it referenced in your classpath, as well as the "weblogic.jar" file, located in the same directory.

 

JAX-RPC client

The principle remains the same as the generation of the webservice : an ANT script calling a task whose type can ben determined by a simple attribute.

<target name="build-client">

      <mkdir dir="${dest.dir}" />

      <clientgen type="JAXRPC"

      wsdl="http://localhost:7001/PdfSaver/PdfSaverService?WSDL"

      destDir="${dest.dir}" classpath="${java.class.path}"

      packageName="${dest.package}" />

</target>

 

Generating and calling the JAX-WS client

<target name="build-client">

      <mkdir dir="${dest.dir}" />

      <clientgen type="JAXWS"

      wsdl="http://localhost:7001/PdfSaver/PdfSaverService?WSDL"

      destDir="${dest.dir}" classpath="${java.class.path}"

      packageName="${dest.package}" />

</target>


Generated classes

The main difference is the way artifacts are generated :

Artifacts

 

Calling the client

Common code

Here's the method called to read the file from the file system and convert it to a byte array.

      private byte[] readBinaryFile() throws Exception {

            File f = new File("path/to/myPdf.pdf");

            FileInputStream fis = new FileInputStream(f);

            byte[] tab = new byte[fis.available()];

            fis.read(tab);

            return tab;

      }

 

JAX-RPC

Considering the classes shown above, here is the client code for calling the JAX-RPC webservice.

public void callMethodWithJaxRpcClient() {

      try {

            webservice.client.jaxrpc.PdfSaverService service =

                  new webservice.client.jaxrpc.PdfSaverService_Impl();

            byte[] file = readBinaryFile();

            service.getPdfSaverSoapPort().savePdf(file);

      } catch (Exception e) {

            e.printStackTrace();

      }

}

 

JAX-WS

Considering the classes shown above, here is the client code for calling the JAX-WS webservice.

public void callMethodWithJaxWSClient () {

      try {

            webservice.client.jaxws.PdfSaverService serviceJaxws =

                  new webservice.client.jaxws.PdfSaverService();

            byte[] file = readBinaryFile();

            serviceJaxws.getPdfSaverPort().savePdf(file);

      } catch (Exception e) {

            e.printStackTrace();

      }

}

If everything went well, you should have your file located in the directory "pdf" located just under the domain directory.

Main differences

As shown in a previous section, artifacts are quite differents.

The WAR generated have different sizes :

Ø      8Kb using JAX-RPC

Ø      3Kb using JAX-WS

And the WSDL generated quite different as well.

Take a look at them.

7 comments:

rkk_blogger said...

Good article. Helpful.

Maxence Button said...

Thank you !
That's exactly the reason why I wanted to write on a blog : help people to use WebLogic :)

Unknown said...

Hello,

I tried succesfully your sample on wls 10. But I didn't succeed in throwing a javax.xml.rpc.soap.SOAPFaultException in order to get control on the exception detail sent to the client.

Here's a code abstract :

Detail detail = null;
try {
SOAPFactory soapFactory = SOAPFactory.newInstance();
detail = soapFactory.createDetail();
} catch (SOAPException e) {
}
QName faultCode = null;
String faultString = "the fault string";
String faultActor = "the fault actor";
throw new SOAPFaultException(faultCode, faultString, faultActor, detail);

Any idea or experience ?

Maxence Button said...

Hi Frédéric,

Well for that kind of question, I would strongly suggest that you post it on http://forums.oracle.com.

It will spread your question to the community and help people who may encounter your problem in the future.

Regards.

Unknown said...

I want to add my thanks--I needed a simple side by side comparison and the sequence of events. The oracle weblogic tutorial is based around their Weblogic Workshop, which we are not using. We'll be using clientGen. Thanks for taking the time to write this!

Maxence Button said...

Thanks Joy for the kind word ! :)

Unknown said...

Hi,

Have you tried implementing WS-Security on JAX-WS webservices for weblogic server 10/10.2 ?