views:

133

answers:

3

I do have something more specific in mind, however:

Each web service method needs to be wrapped with some boiler place code (cross cutting concern, yes, spring AOP would work great here but it either doesn't work or unapproved by gov't architecture group). A simple service call is as follows:

@WebMethod...
public Foo performFoo(...) {

   Object result = null;
   Object something = blah;
   try {
      soil(something);

      result = handlePerformFoo(...);
    } catch(Exception e) {
       throw translateException(e);
    } finally {
       wash(something);
    }
    return result;
}

protected abstract Foo handlePerformFoo(...);

(I hope that's enough context). Basically, I would like a hook (that was in the same thread - like a method invocation interceptor) that could have a before() and after() that could could soil(something) and wash(something) around the method call for every freaking WebMethod.

Can't use Spring AOP because my web services are not Spring managed beans :(

HELP!!!!! Give advice! Please don't let me copy-paste that boiler plate 1 billion times (as I've been instructed to do).

Regards, LES

+1  A: 

Is AspectJ an option since Spring is out?

Or, can you use Reflection, and just redesign your application to work with this concept?

For a review on reflection you can look at this article: http://onjava.com/pub/a/onjava/2007/03/15/reflections-on-java-reflection.html

Or redesign your class to use an abstract class, so performFoo would be in the abstract class, so you don't do copy and paste. You are almost there in your example.

James Black
A: 

I ended up using the JAX-WS Commons Spring Extention and made my web service impl a spring managed bean and used around advice to handle all that boiler plate in one place.

If I wanted to maintain the original constraint of no AOP, I suppose I could have created an interface and a helper method as follows:

interface Operation<T> {
    T execute();
}

public T doOperation(Operation<T> op) {

    // before advice

    try {
        return op.execute();
    } catch(Throwable ex) {
        // handle ...
    } finally {
        // clean up ...
    }
}

Finally, the business methods would be coded as follows:

public Result computeResult(final String item, final int number) {
    return doOperation(new Operation<Result>(){
        public Result execute() {
            return new Result(item + ": processed", number * 5);
        }
    });
}

Basically, each business method would use the doOperation helper method in it's body and an anonymous class containing the code that needs to execute within the context created by the doOperation method. I'm sure there's a name for this pattern (reminds me of the Loan Pattern).

LES2
A: 

The best way would be to use Handlers, but you would have to annotate all your services with the @HandlerChain annotation:

@WebService(name = "AddNumbers")
@HandlerChain(file = "handlers.xml")  // put handlers.xml in WEB-INF/classes
public class AddNumbersImpl implements AddNumbers
{
...
}

The file handlers.xml would define your handlers:

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee"&gt;
  <handler-chain>
    <handler>
      <handler-name>LoggingHandler</handler-name>
      <handler-class>demo.handlers.common.LoggingHandler</handler-class>
    </handler>
  </handler-chain>
</handler-chains>

Finally, implement your Handler class like this:

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {

   // this is called before invoking the operation and after invoking the operation
   public boolean handleMessage(SOAPMessageContext ctx) {
      log(ctx);
      return true;
   }

   public boolean handleFault(SOAPMessageContext ctx) {
      log(ctx);
      return true;
   }
}

More details here.

alves