Tuesday, January 16, 2007

Java Web Service Exception Handling

This assumes that you are using JAX-RPC which uses SOAP 1.1 to implement a web service, and that the web service is being consumed by .Net (1.1 or 2.0). If you are using WS 2.0 there are some different options.

 

While it is possible to just throw an plain old Exception in your java web service, it will show up your .Net client as a exception. The problem is determining what exception you have catch once you get it. In this situation we need a code that can be used in the client to identify the exception without try to rely on the message of the exception since this is typically semi user-friendly text. Exception class doesn’t have the concept of a code to identify the exception. The good news is SOAPFaultException has the concept of a code and it also allows you to attach any other data that may be useful.

 

Creating a SOAPFaultException can be a little messy, so I recommend created a convenience method to encapsulate this. In case this isn’t clear, this goes in your java web service.

 

// Creates and returns a SOAPFaultException. Throws one if there is an error creating

// Should be Client or Server

// If it is Client then message should NOT be resent without change

// i.e. Server.Fault or Client.Fault

public SOAPFaultException NewException(String faultType, String errorCode, String errorMessage, String webServiceOperationName) throws SOAPException

{

 

       // The faultcode element provides an algorithmic mechanism for identifying the fault.

//SOAP defines a small set of SOAP fault codes covering basic SOAP faults.

       QName faultCode = new QName("http://FrontLineWebService/" + webServiceOperationName, faultType + "." + errorCode);

 

       // The faultstring provides a human-readable description of the SOAP fault and is not intended for algorithmic processing.

       String faultString = errorMessage;

 

       // The faultactor element provides information about which SOAP node on the SOAP message path caused the fault to happen.

//It indicates the source of the fault.

       String faultActor = "http://FrontLineWebService/" + webServiceOperationName;

 

       // The detail element is intended for carrying application specific error information related to the SOAP Body.

       Detail faultDetail = SOAPFactory.newInstance().createDetail();

 

       // Define what the body of the email should be in terms of XML. You can put whatever data you want here

       faultDetail.addChildElement("ErrorMessage").addTextNode(errorMessage);

       faultDetail.addChildElement("ErrorCode").addTextNode(errorCode);

 

       // for more info on params: see http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383507

       throw new SOAPFaultException(faultCode, faultString, faultActor, faultDetail);

 

}

 

Here is an example of how you would throw the SOAPFaultException in your web service.

 

 

public void testMethod() throws Exception, SOAPFaultException, java.rmi.RemoteException

{

 

       throw NewException("Server.Fault", "TEST_CODE", "This is only a test description in English", "testMethod");

}

 

 

Now that you can easily throw a SOAPFaultException (SoapException in .Net), you are all set. Here is an example of catching it in your .Net client.

 

using System.Web.Services.Protocols;

...

 

try

{

    MyWS ws = new MyWS();

 

    ws.testMethod(new testMethod());

   

}

catch (SoapException ex)

{

    if (ex.Code.Name == "Server.Fault.TEST_CODE")

    {

        // do stuff here

    }  

}

No comments: