Web Service Exception Handling

In most applications, exceptions tend to be either application-based (for instance, no cash is left in an ATM machine, so you can't withdraw any money) or infrastructure-based (for instance, someone has accidentally tripped over a power cable in the data center). Exceptions in Web services follow a similar pattern. Exceptions can be thrown as part of the Web service (for example, you cannot place an order because the markets are not open ) or if the service cannot be activated (for example, the particular machine cannot connect to the server).

Understanding how these exceptions are trapped and caught in the context of interoperability between .NET and Java is very useful: it can help determine the appropriate course of action within an application, especially when writing a client on one of the two platforms in order to access a Web service published on the other. Using the previous samples, this section formalizes exception handlingshowing which exceptions can be thrown, given a number of circumstances on both the Java and .NET platforms.

Web Service URL Not Available

This is an infrastructure-specific exception. It can occur when no part of the Web service is available but when the machine can be accessed (for instance, when trying to view the service with a browser prompts an HTTP 404Not Found error).

.NET Client to Unavailable Java Web Service

When this exception occurs, the .NET client reports a System.Net.WebException :

 System.Net.WebException  The underlying connection was  closed: Unable to connect to the remote server. 

The System.Net.WebException inherits from System.Exception , so all the general Exception fields ( Message , InnerException , and so on) are available. System.Net.WebException also contains properties for Response and Status , which will provide additional information about the reason for the exception.

Java Client to Unavailable .NET Web Service

When this exception occurs, the Java client reports an electric.registry.RegistryException to indicate that the .NET Web service could not be reached:

 Exception in thread "main" electric.registry.RegistryException:  could not bind to path:  http://localhost/dotNETWebService/StockService.asmx?WSDL 

The electric.registry.RegistryException defines a getClause method that returns the underlying Exception that can be used to indicate the reason for failure. In this example of the machine being unavailable, the underlying exception is one of java.rmi.ConnectionException .

Web Service Method Not Available

The second type of exception we'll examine is specific to the Web service itself. In this exception, the WSDL contract is available, but the Web service method that is exposed no longer exists. An example of this occurs when the client has been built based upon methods exposed by an old version of a WSDL document. The exposed methods have changed and are no longer available for the client to consume .

.NET Client to Unavailable Java Web Service Method

The .NET client throws a System.InvalidOperationException exception, indicating that it was expecting some kind of XML document but that it received something different (probably the HTTP 404Not Found error page):

 System.InvalidOperationException: Client found response  content type of '', but expected 'text/xml'. 

Java Client to Unavailable .NET Web Service Method

The GLUE toolkit throws an exception of type electric.util.WrappedException :

 Exception in thread "main" electric.util.WrappedException: java.lang.NoSuchMethodException: BuyStocks 

This exception defines a getException method, which returns a more specific exception to trap. In this instance, a java.lang.NoSuchMethodException indicates that the method is no longer part of the WSDL contract.

Security-Specific Exceptions

You saw this type of exception come up in the previous section, "Web Services Authentication and Authorization." Assuming that the Web service is functional, you can still receive an exception if the HTTP authentication credentials that you supply are not sufficient to access the service.

Unauthorized .NET Client to Java Web Service

The .NET client throws a System.Net.WebException , indicating that the status is Access Denied:

 System.Net.WebException: The request failed with HTTP  status 401: Unauthorized. 

Unauthorized Java Client to .NET Web Service

For the Java client, a RegistryException is thrown, indicating that the client could not bind to the service:

 Exception in thread "main" electric.registry.RegistryException:  could not bind to path:  http://localhost/dotNETWebService/StockService.asmx?WSDL 

Application-Specific Exceptions

The final type of exception we'll discuss is an application-specific exception that has been thrown as part of the Web service code. Application-specific exceptions differ from infrastructure-based exceptions in that they tie in more tightly to the SOAP specification. As you've seen with data types so far in the book, exceptions that mean something in .NET don't necessarily map to exceptions that occur in Java. (After all, an exception on either platform is still a data type, so the same rules apply.) A StockNotFoundException thrown from a .NET Web service doesn't mean anything to a Java client. Even if you could map exceptions between the two platforms, it would be an exhaustive process.

How SOAP Defines Exceptions

To help overcome this (and to help with non-.NET and non-Java Web service consumers), SOAP defines an element known as a SOAP Fault . This fault element defines four subelements:

  • faultcode A code that indicates the type of the fault.

  • faultstring Some human-readable description of the fault.

  • faultactor Because SOAP messages can be carried among a number of nodes in a delivery path, this is an optional field to specify where the fault occurred.

  • detail An XML document describing the detail of the fault.

This SOAP Fault element maps to each platform in one of the two ways discussed next .

Both the .NET Framework and GLUE map user -thrown exceptions to SOAP exceptions as described in the following sections.

.NET Client Connecting to a Java Web Service Method that Throws an Exception

For the .NET client, an application exception is caught as a System.Web.Services.Protocols.SoapException :

 System.Web.Services.Protocols.SoapException: Sorry, Stock Service  is Unavailable 

The SoapException class is the exception that implements the details of the SOAP Fault. From properties within SOAPException , you can investigate the Message , Code , Actor , and Detail from the SOAP Fault specification. Likewise, if you know that the code will throw such an exception, you might want to throw a custom exception that implements SOAPException in order to prepopulate these details.

This exception can actually be demonstrated with one of the samples shown earlier. The sample code that exposed an EJB by using Web services made a simulated call to find a stock based on the ticker that was passed. If the stock ticker was not found, the method on the Session Bean threw a StockNotFoundException , a custom exception that was part of the sample.

This exception can be caught in .NET as a SoapException . If you look back at the sample code for the .NET client that calls this exposed EJB (in the C:\Interoperability\Samples\Point\WebServices\JavaEJB\dotNETClient directory), this exception is shown with the following try/catch block:

 try {     FinancialServices.StockService ss =          new FinancialServices.StockService();     Console.WriteLine("\nYour sale "          +((ss.sellStocks("CONT",100))? "completed" : "failed")); } catch(SoapException se) {     Console.WriteLine(se.Detail.InnerText); } 

The detail for the exception (part of the SOAP Fault definition) is returned as an XML element and can be examined as shown in the catch block of the code. To test this, revisit the EJB sample at the start of this chapter and change the stock ticker in the client from "CONT" to a ticker that will not be recognized by the EJB (for example, "COHO").

 Stock was not found     at com.microsoft.samples.ejb.StockSessionBean.sellStocks     (Unknown Source)     at java.lang.reflect.Method.invoke(Native Method)     (rest of the exception follows) 

This shows that the message thrown by the original exception ("Stock was not found") is passed as part of the SoapException that's caught on the client. Although application-specific exception types are not communicated by Web services, following this practice of wrapping Web service invocations in a try/ catch block can prove a useful way to trap these types of exceptions and return a suitable result to the end user.

Java Client Connecting to a .NET Web Service Method that Throws an Exception

For the Java client, electric.util.WrappedException is caught for each application-specific exception:

 Exception in thread "main" electric.util.WrappedException:  SOAPException(Server: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception:  Sorry, Stock Service is Unavailable 

The WrappedException contains an exception of type electric.soap.SOAPException . This SOAPException contains methods ( getSOAPCode , getSOAPActor , and getSOAPDetail ) that can be used to further interrogate the SOAP-specific details of the exception, similar to the way the previous .NET exception type worked.

Exception Conclusion

Overall, these examples give a basic insight into how exceptions can be handled and caught when using Web services that bridge .NET and J2EE. As a general recommendation, I suggest that anyone writing a client to consume a Web service be aware of the types of exceptions that can be thrown (both infrastructure and application) and know how to deal with them to give the best overall experience and information to the user.

Microsoft. NET and J2EE Interoperability Toolkit
Microsoft .NET and J2EE Interoperability Toolkit (Pro-Developer)
ISBN: 0735619220
EAN: 2147483647
Year: 2003
Pages: 132
Authors: Simon Guest

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net