Hi

On 05/10/12 10:09, Juan José Pérez Consuegra wrote:
Hello all,

I' trying to send a custom error message to client when a non authorization
intent has been detected. I'm using invoker to extract user and password
and I want to send back a Response or launch an Exception. If I use a
Response the received message in client is empty with status 200 OK.

And if I throw a webapplicationexception like this:


<ns1:XMLFault 
xmlns:ns1="http://cxf.apache.org/bindings/xformat";><ns1:faultstring
xmlns:ns1="http://cxf.apache.org/bindings/xformat
">javax.ws.rs.WebApplicationException</ns1:faultstring></ns1:XMLFault>

with server status 500.


Here is my code:
     @Override
     public Object invoke(Exchange exchange, Object requestParams, Object
resourceObject) throws WebApplicationException{
         Message mensaje = exchange.getInMessage();
         AuthorizationPolicy policy =
(AuthorizationPolicy)mensaje.get(AuthorizationPolicy.class);
         if (policy == null) {
             return Response.status(401).build();
//            throw new
WebApplicationException(Response.status(401).build());
         }
         String retUsuario = policy.getUserName();
         String retPassword = policy.getPassword();
         if (autenticacionValida(retUsuario, retPassword)){
             return super.invoke(exchange, requestParams, resourceObject);
         } else {
             return Response.status(401).build();
//            throw new
WebApplicationException(Response.status(401).build());
         }
     }

I think using a custom invoker to enforce the authorization only makes sense if the actual objects to be passed to the resource method can provide some extra context - otherwise use a RequestHandler filter (or preferably ContainerRequestFilter in CXF 2.7.0) - you can simply block a request from there with a custom Response.

If you do need to use the invoker and decide to throw an exception:
this exception now escapes the JAX-RS 'catch' blocks which try to map it to Response with the help of the registered mappers - and this is why you see the above XML-formatted error message - in fact the exception should've been propagated to the servlet layer - guess you configure the endpoint not to propagate.
So, to manage the exceptions thrown from the invoker:
- register custom out fault interceptor - this one can write directly to HTTP output stream if needed. - do not throw the exception - create Response within your custom invoker and 'return new MessageContentList(myResponse)'


May I use an exception mapper?? If so, How I must register the mapper, I
tryed to do that like this:

         sf = new JAXRSServerFactoryBean();
         sf.setResourceClasses(RLABSystemWSRest.class);
         sf.setResourceProvider(RLABSystemWSRest.class,
         new SingletonResourceProvider(new RLABSystemWSRest()));
         sf.setAddress("http://localhost:9001/";);
         RestInvoker invoker = new RestInvoker();
         RestExceptionMapper mapper = new RestExceptionMapper();
         sf.setInvoker(invoker);
         sf.setProvider(mapper);
         server = sf.create();

with this code as mapper:

@Provider
public class RestExceptionMapper implements
         ExceptionMapper<WebApplicationException>  {

     @Override
     public Response toResponse(WebApplicationException ex) {
         ResponseBuilder rb = Response.status(401);
         return rb.build();
     }

}

but it doesn't work.

I have another question, is about the stack trace in mi server console, I
would like it doesn't appear, or show a custom message too, when I return a
Response nothing happens of course, but when I throws a
webapplicationexception added to the result in client I have this in my
server:


Because the exception escapes, the CXF PhaseInterceptorChain prints this stack trace by default - you can register CXF FaultListener that can make it 'silent' - but you only need it if you decide to continue throwing the exceptions from the invoker

Cheers, Sergey


Advertencia: Interceptor for {
http://ws.cserver.related.scc.uned.es/}RLABSystemWSRest has thrown
exception, unwinding now
javax.ws.rs.WebApplicationException
     at
es.uned.scc.related.cserver.ws.RestInvoker.invoke(RestInvoker.java:23)
     at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:94)
     at
org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
     at
org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:94)
     at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
     at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:122)
     at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:344)
     at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:310)
     at
org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)
     at
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)
     at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:941)
     at
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:188)
     at
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:875)
     at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
     at
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)
     at
org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
     at org.eclipse.jetty.server.handler.HandlerWrapper.handl
      .........



thanks in advance,

Juanjo



--
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Reply via email to