On Jun 6, 2008, at 4:37 PM, Wolf, Chris (IT) wrote:
Dan,
You mentioned that CXF interceptors have a performance advantage over
JAX-WS interceptors, such as SOAPHandler implementations because
CXF interceptors don't read in the whole message into DOM.
However, I notice that in the code for SAAJInInterceptor that, in
fact,
this CXF interceptor does just that - builds a DOM of the whole
message
body:
line-109:
XMLStreamReader xmlReader =
message.getContent(XMLStreamReader.class);
StaxUtils.readDocElements(soapMessage.getSOAPBody(),
xmlReader, true);
DOMSource bodySource = new
DOMSource(soapMessage.getSOAPPart().getEnvelope().getBody());
xmlReader = StaxUtils.createXMLStreamReader(bodySource);
Is it just that this particular implementation happens to do it that
way?
That particular implementation happens to do it that way. Basically,
the WSS4J library that we use to do the ws-security processing
requires the DOM. There are "talks" about making it more Stax based,
but that work hasn't started at all. Thus, for ws-security, we do
need to do the SAAJ thing. However, if you aren't doing ws-security,
normally the SAAJInInterceptor isn't on the chain so that doesn't
occur. We stream directly to/from the Stax streams to/from the JAXB
objects for the Body parts. The SOAP headers are slightly
different. We read the soap headers into DOM elements in the
ReadHeadersInterceptor and store them in a list in the message.
Thus, any interceptor after that interceptor can get the headers and
process them without having the body parsed at all. Thus, if you
just need some SOAP headers, it's more performant to use the
interceptors. Things like the ws-addressing and ws-rm are
implemented that way.
Dan
Thanks,
-Chris
P.S. the company mail client, Outlook, makes difficult to properly
quote
mail responses - sorry.
-----Original Message-----
From: Daniel Kulp [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 05, 2008 3:29 PM
To: [email protected]
Subject: Re: Using AOP in CXF service impl
On Jun 5, 2008, at 2:51 PM, Wolf, Chris (IT) wrote:
Dan,
Thanks for the help. Yes, it was Spring's AOP "ProxyFactory" that
was
wrapping the SEI implementation class in a dynamic proxy, and that
was
the only issue. I got confused in the debugger with the mistaken
impression that there was more then one layer of dynamic proxying
occuring.
In any case, I resolved the issue (with Ian's suggestion).
Now I am wondering -- why would I not just use a CXF interceptor?
You definitely could do that if that's easier. Depends on your
requirements. Doing the Spring AOP stuff allows use of the Acegi
annotations and stuff so if you're used to that, thats very easy.
Is there any advantage to using an implementation of
AbstractPhaseInterceptor vs. using an implementation of
javax.xml.ws.handler.soap.SOAPHandler?
In the later case, it seems that being JAX-WS API would mean greater
portability, so wouldn't that be better?
It's a "portability" vs "performance/scalability" trade off that you
need to balance for yourself. A JAX-WS SOAPHandler has to have the
entire SAAJ model of the soap message available. Thus, it kind of
breaks the streaming aspects of CXF. It also consumes more memory as
you have the "DOM" form in memory. That triggers more garbage
collections, etc.... If you have really large soap messages, it can
be really troublesome.
A CXF interceptor can get around that. If you just need the basic
auth tokens from the protocol headers, you can just grab those and
ignore the contents of the message entirely. If you just need the
SOAP headers, you can look at them without touching the body stuff.
etc....
Basically, you have to weigh your priorities and decide which
direction
is right for your project.
Dan
Thanks,
-Chris
-----Original Message-----
From: Daniel Kulp [mailto:[EMAIL PROTECTED]
Sent: Saturday, May 24, 2008 10:05 PM
To: [email protected]
Subject: Re: Using AOP in CXF service impl
We definitely have seen people using Spring AOP with CXF, but I think
they've all used Spring configuration for setting up the endpoints
and
stuff. That said, it should definitely be doable from API's since
all the spring config does is configure the same objects via the API.
CXF doesn't use proxies on the server side. Spring must be doing
something there.
Dan
On May 23, 2008, at 1:52 PM, Wolf, Chris (IT) wrote:
I tried using Spring's AOP support classes to implement service
authorization code in my CXF service, for the reason of not
cluttering
up my service code with security code (and maybe will also add
auditing/tracing). This seems to be to classic use-case for AOP.
Unfortunately, the AOP implementation appears to use dynamic proxy
techniques (instance of java.lang.reflect.Proxy) but it also appears
that CXF uses dynamic proxies for the service implementation,
because
if I break in the ServiceCallPointcut code, the targetClass appears
to
*also* be an instance of java.lang.reflect.Proxy, so maybe there's
an
issue using Spring AOP on dynamic proxies.
Has anyone tried using AOP techniques in CXF service code?
Thanks for any suggestions.
-Chris
[...]
import javax.xml.ws.WebServiceContext; import
javax.xml.ws.handler.MessageContext;
org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
static class ServiceCallPointcut extends StaticMethodMatcherPointcut
{
public boolean matches(Method m, Class targetClass) {
return (targetClass == this.getClass() &&
m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
}
}
static class AuthenticationChecker implements MethodBeforeAdvice {
public void before(Method m, Object[] args, Object target) throws
Throwable {
System.out.println("*** Calling " + m.getName());
// transport-portable MessageContext
MessageContext ctx =
((SecAdminImpl)target).context.getMessageContext();
// transport-specific request/response, cxf-specific property
names
HttpServletRequest request = (HttpServletRequest)
ctx.get(MessageContext.SERVLET_REQUEST);
HttpServletResponse response = (HttpServletResponse)
ctx.get(MessageContext.SERVLET_RESPONSE);
Cookie[] cookies = request.getCookies();
}
}
MyServiceImpl svc = new MyServiceImpl();
ProxyFactory factory = new ProxyFactory(svc); factory.addAdvisor(new
DefaultPointcutAdvisor(new ServiceCallPointcut(), new
AuthenticationChecker()));
--------------------------------------------------------
NOTICE: If received in error, please destroy and notify sender.
Sender does not intend to waive confidentiality or privilege. Use of
this email is prohibited when received in error.
---
Daniel Kulp
[EMAIL PROTECTED]
http://www.dankulp.com/blog
--------------------------------------------------------
NOTICE: If received in error, please destroy and notify sender.
Sender does not intend to waive confidentiality or privilege. Use of
this email is prohibited when received in error.
---
Daniel Kulp
[EMAIL PROTECTED]
http://www.dankulp.com/blog
--------------------------------------------------------
NOTICE: If received in error, please destroy and notify sender.
Sender does not intend to waive confidentiality or privilege. Use of
this email is prohibited when received in error.
---
Daniel Kulp
[EMAIL PROTECTED]
http://www.dankulp.com/blog