What happens if you don't extend that class and just add the required fields
to the exception (i.e. faultCode and what not?) Does XFire still pick it up?
That way you aren't coupling your service with XFire...

On 11/27/06, Bill Burton <[EMAIL PROTECTED]> wrote:

Hello,

On 11/27/06, Andres Bernasconi <[EMAIL PROTECTED]> wrote:
> Wow...but now you are stucked with XFire..even inside your busines
logic...

Nope.  My DAO's don't catch any exceptions including Spring's JDBC
RuntimeExceptions.  It's the service implementation that's traps
Spring's RuntimeException and then rethrows this new exception
extended from XFireFault.

> We are using Wrappers in our project. I guess it suits us just fine
because
> we always return the same type of object for all operations, so we only
have
> one wrapper. Still I'm no fanatic of either approach...just use what
suits
> you best... Still, I guess that this particular case (extending your
> exceptions from XFireException) is something I would not have done.

If it would have made the C# developer's job significantly easier or
if it was a third-party application that couldn't be changed, then I'd
consider a wrapper class as a compromise but it appears catching the
faults will be easy in C#.

One problem I found was that because I'm extending
org.codehaus.xfire.fault.XFireFault, the Aegis default mapping is
generating corresponding properties including one for faultCode with
has a QName type.  This caused the schema validation to fail so I
added the following Aegis mapping file to hide most of the exception's
properties:

RecordNotFound.aegis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xsi:schemaLocation="http://xfire.codehaus.org/schemas/1.0/mapping.xsd";>
    <mapping>
        <property name="faultCode" ignore="true"/>
        <property name="detail" ignore="true"/>
        <property name="namespaces" ignore="true"/>
        <property name="subCode" ignore="true"/>
   </mapping>
</mappings>

XFire is still setting the faultcode and faultstring properly so there
doesn't seem to be any need for these properties.

-Bill

>
> On 11/27/06, Bill Burton <[EMAIL PROTECTED]> wrote:
> >
> > Hello,
> >
> > Thanks everyone for the helpful responses.
> >
> > Although it would be possible to create a wrapper class, I'd really
> > rather not given that I think it should be easy to check for the fault
> > in the C# client.  If the client was a third-party application in
> > which I had absolutely no control, that would be a different matter.
> >
> > What I would like to do is find some happy medium that works well with
> > an XFire service and C# clients.  Here's what I found so far using an
> > XFire Aegis mapped service and by writing my own C# client:
> >
> > * Throwing a checked exception (that's specified in your service
> > interface) causes XFire to generate a SOAP fault where the faultcode
> > == "soap:Server" and faultstring contains the exception text message.
> >
> > * In C#, a SOAP fault from XFire translates into a SoapException
where:
> >   - SoapException.Message contains the message text specified to the
> > Java Exception.
> >   - SoapException.Code.Name contains the faultcode "Server" (soap: is
> > stripped off)
> >   - SoapException.Details.FirstChild.Name is the name of
> the Java
> > Exception, i.e. "RecordNotFoundException".
> >
> > Although it's trivial for the C# application to check the exception
> > message, I'd rather specify a meaningful code that's easy to check.
> > Right now, the faultcode shows up as:
> >     <faultcode>soap:Server</faultcode>
> > which provides no indication of the problem.  I'd like to change it to
> > something like:
> >     <faultcode>soap:Server.RecordNotFound</faultcode>
> > as from what I've read in the SOAP specs, this is how error codes can
> > be specified
> (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383510).
> >
> > So my question now is, how do I specify my own error code for the SOAP
> > fault code?
> >
> > Well, that was my question.  It turned out to by very easy to
> > customize the fault code--just have my exception class extend
> > XFireFault instead of something else and then specify the fault code
> > in a QName.  My Exception class now looks like this:
> >
> > public class RecordNotFoundException extends XFireFault {
> >     public RecordNotFoundException() {
> >         super();
> >     }
> >     public RecordNotFoundException(String message) {
> >         super(message, new QName(null, "soap:Server.RecordNotFound"));
> >     }
> > }
> >
> > The service interface is:
> > public interface PersonService {
> >     public Person findByLoginId(String id) throws
RecordNotFoundException;
> > }
> >
> > which generates (slightly abbreviated):
> >       <soap:Fault>
> >          <faultcode>soap:Server.RecordNotFound</faultcode>
> >          <faultstring>No record with id 123100782F was found by the
> > findByLoginId method!</faultstring>
> >       </soap:Fault>
> >
> > which is exactly what I wanted.
> >
> > The C# SOAP fault checking is now very easy:
> > try {
> >     person = personService.findByLoginId("123100782F");
> > } catch (System.Web.Services.Protocols.SoapException se)
> {
> >     if (!se.Code.IsEmpty && se.Code.Name.Equals("Server.RecordNotFound
"))
> {
> >         Console.WriteLine("Record was not found: " + se.Message);
> >     }
> > }
> >
> > Thanks!
> > -Bill
> >
> > On 11/22/06, Tomek Sztelak <[EMAIL PROTECTED]> wrote:
> > > Hi
> > >
> > > On 11/21/06, Bill Burton < [EMAIL PROTECTED]> wrote:
> > > > Hello,
> > > >
> > > > I've written a simple service that provides a way to lookup Person
> objects
> > > > by id or email address. The Person object just has some name and
> address
> > > > information. When a record is not found, I'm catching the runtime
> exception
> > > > from the Spring JDBC API, and rethrowing a checked exception which
> causes
> > > > XFire to generate a SOAP fault as follows:
> > > >
> > > > <soap:Envelope
> > > >
> xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";
> > > > xmlns:xsd=" http://www.w3.org/2001/XMLSchema "
> > > >
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
> > > >    <soap:Body>
> > > >       <soap:Fault>
> > > >          <faultcode>soap:Server</faultcode>
> > > >          <faultstring>No record with id 000123005 was found by the
> findById
> > > > method!</faultstring>
> > > >          <detail>
> > > >             <RecordNotFoundException xmlns="
> http://webservice.teds.pms"/>
> > > >          </detail>
> > > >       </soap:Fault>
> > > >    </soap:Body>
> > > > </soap:Envelope>
> > > >
> > > > Right now, I'm just using the default generated bindings in my
Spring
> > > > applicationContext.xml
> > > >
> > > >     <bean name="PersonService"
> > > > class="org.codehaus.xfire.spring.ServiceBean">
> > > >         <property name="serviceBean" ref="PersonServiceImpl"/>
> > > >         <property name="serviceClass"
> > > > value="pms.teds.webservice.PersonService"/>
> > > >     </bean>
> > > >
> > > > but plan to switch to Aegis to have better control over the
mapping
> for
> > > > other reasons.
> > >
> > > Aegis is a default binding, so you are already using it:)
> > >
> > > > However, the person who's writing a C# .NET client to handle this
> complains
> > > > that it's hard to check for a fault whereas if I were to return an
> error
> > > > code and error text in my Person object, he would have no
problem.  As
> the
> > > > Person object is supposed to be a reflection of the database
columns,
> I
> > > > really don't want to change it in this manner.
> > > >
> > > > What are the best practices for generating an error such as
"record
> not
> > > > found" or "database not available" cases?
> > >
> > > I think that adding error codes to your data model object is a bad
> > > idea. You should use exception ( SOAP fault ), as you do now.
> > >
> > > > Thanks for any assistance,
> > > > -Bill
> > > > --
> > > > Bill Burton < bburton ayht mail daht com>
> > > >
> >
> >

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to