You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Curtis Garman <cu...@gmail.com> on 2014/10/15 18:39:54 UTC

Trouble configuring custom ResponseExceptionMapper

I have a java 8, Spring 4.1.1, cxf 3.0.1 app where I am tring to implement a
custom ResponseExceptionMapper for all exceptions returned to my rest
client. When I start my application, everything starts fine. However even
when I start the app with DEBUG logging turned on, I see nothing related to
my exception mapper. To test the functionality, I am passing invalid creds
to the rest service I'm consuming. According to my mapper, the 403 response
should be converted to a custom AuthorizationException...however as can be
seen from my log, the 403 is being converted to a jaxrs ForbiddenException.
Can anyone help me get things wired correctly? I noticed some of the
interfaces changed between cxf 2.x and 3.x. Is there a different interface
that I should be implementing? Implementing ExceptionMapper on the service
provider side works just fine.

 

 

package test.webservice.rest.exception;

 

import javax.ws.rs.WebApplicationException;

import javax.ws.rs.core.Response;

import javax.ws.rs.ext.Provider;

 

import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

 

@Provider

@Component("exceptionMapper")

public class CustomResponseExceptionMapper implements
ResponseExceptionMapper<Exception> {

 

    private static final Logger LOGGER =
LoggerFactory.getLogger(CustomResponseExceptionMapper.class);

 

    @Override

    public Exception fromResponse(Response response) {

        LOGGER.debug(String.format("Executing %s",
CustomResponseExceptionMapper.class));

        Response.Status status =
Response.Status.fromStatusCode(response.getStatus());

        LOGGER.debug(String.format("Status: %s", status.getStatusCode()));

        switch (status) {

            case BAD_REQUEST:

                throw new
InvalidInputException(response.getHeaderString("exception"));

            case UNAUTHORIZED:

                throw new
AuthorizationException(response.getHeaderString("exception"));

            case FORBIDDEN:

                throw new
AuthorizationException(response.getHeaderString("exception"));

            case NOT_FOUND:

                throw new
EmptyResultDataAccessException(response.getHeaderString("exception"));

            case CONFLICT:

                throw new
DuplicateKeyException(response.getHeaderString("exception"));

            default:

                throw new
WebApplicationException(response.getHeaderString("exception"));

        }

    }

 

}

 

 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 
xmlns:context="http://www.springframework.org/schema/context"

                xmlns:cxf="http://cxf.apache.org/core"

                xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client"

                xsi:schemaLocation="

                                http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd

                               http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

                               http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd

                               http://cxf.apache.org/jaxrs-client
http://cxf.apache.org/schemas/jaxrs-client.xsd">

 

                <import resource="classpath:META-INF/cxf/cxf.xml"/>

                <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

                

                <bean id="jsonProvider"
class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>

 

    <jaxrs-client:client id="albumClient"

                serviceClass="org.apache.cxf.jaxrs.client.WebClient"

 
address="http://localhost:8080/rest-provider/services/album"

                                username="test"

                                password="test">

                                <jaxrs-client:headers>

                                                <entry key="Accept"
value="application/xml"/>

                                </jaxrs-client:headers>

                <jaxrs-client:providers>

                                                <ref bean="requestFilter" />

                                <ref bean="jsonProvider" />

                                <ref bean="responseFilter" />

                                                <ref bean="exceptionMapper"
/>

                                </jaxrs-client:providers>

                </jaxrs-client:client>

 

                <context:component-scan
base-package="test.webservice.rest.exception" />

    <context:component-scan base-package="test.webservice.rest.filter" />

                <context:component-scan
base-package="test.webservice.rest.service" />

 

</beans>

 

 

 

HTTP Status 500 - Request processing failed; nested exception is
javax.ws.rs.ForbiddenException: HTTP 403 Forbidden

type Exception report

message Request processing failed; nested exception is
javax.ws.rs.ForbiddenException: HTTP 403 Forbidden

description The server encountered an internal error that prevented it from
fulfilling this request.

exception

 

org.springframework.web.util.NestedServletException: Request processing
failed; nested exception is javax.ws.rs.ForbiddenException: HTTP 403
Forbidden

 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkSer
vlet.java:973)

 
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java
:852)

                javax.servlet.http.HttpServlet.service(HttpServlet.java:618)

 
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.ja
va:837)

                javax.servlet.http.HttpServlet.service(HttpServlet.java:725)

 
org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(Shal
lowEtagHeaderFilter.java:81)

 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestF
ilter.java:107)

 
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

root cause

javax.ws.rs.ForbiddenException: HTTP 403 Forbidden

 
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

 
sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

                java.lang.reflect.Constructor.newInstance(Unknown Source)

 
org.apache.cxf.jaxrs.client.AbstractClient.convertToWebApplicationException(
AbstractClient.java:478)

 
org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:886)

 
org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:854)

 
org.apache.cxf.jaxrs.client.WebClient.invokeAndGetCollection(WebClient.java:
513)

 
org.apache.cxf.jaxrs.client.WebClient.getCollection(WebClient.java:589)

 
test.webservice.rest.service.SimpleAlbumService.findAlbums(SimpleAlbumServic
e.java:28)

 
test.webservice.rest.servlet.AlbumController.list(AlbumController.java:27)

                sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

                sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)

                java.lang.reflect.Method.invoke(Unknown Source)

 
org.springframework.web.method.support.InvocableHandlerMethod.invoke(Invocab
leHandlerMethod.java:215)

 
org.springframework.web.method.support.InvocableHandlerMethod.invokeForReque
st(InvocableHandlerMethod.java:132)

 
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandle
rMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)

 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA
dapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)

 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA
dapter.handleInternal(RequestMappingHandlerAdapter.java:721)

 
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.hand
le(AbstractHandlerMethodAdapter.java:83)

 
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServl
et.java:943)

 
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServle
t.java:877)

 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkSer
vlet.java:961)

 
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java
:852)

                javax.servlet.http.HttpServlet.service(HttpServlet.java:618)

 
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.ja
va:837)

                javax.servlet.http.HttpServlet.service(HttpServlet.java:725)

 
org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(Shal
lowEtagHeaderFilter.java:81)

 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestF
ilter.java:107)

 
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)


Re: Trouble configuring custom ResponseExceptionMapper

Posted by Sergey Beryozkin <sb...@gmail.com>.
On 16/10/14 22:12, Curtis Garman wrote:
> Hmm...so I guess what I'm looking for is a way to define a sort of global
> way to map status codes to exceptions so that I don't need to duplicate my
> same try/catch logic around every client call. Aside from the
> ResponseExceptionMapper, is there any way to do this for WebClient?
WebClient (and JAX-RS 2.0 Client/WebTarget implementation that delegates 
to WebClient internally) is HTTP-centric API, you can use the methods 
returning JAX-RS Response and react to statuses or deal with HTTP 
centric exceptions defined in the spec API that WebClient will throw for 
error statuses. It is there for users who are happy with doing the 
HTTP-centric client programming.

Updating WebClient to map the HTTP statuses to custom Exceptions would 
introduce the ambiguity into the WebClient model of doing HTTP calls and 
would also imply that most of its methods would have to declare checked 
Exception which would not be cool at all.

Why don't you use a proxy API if you'd like the statuses mapped to 
custom exceptions; proxy API is there to 'shield' users from the 
lower-level HTTP details

Sergey

>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: Thursday, October 16, 2014 11:23 AM
> To: users@cxf.apache.org
> Subject: Re: Trouble configuring custom ResponseExceptionMapper
>
> On 16/10/14 17:04, Curtis Garman wrote:
>> I did a little debugging and have discovered that
>> org.apache.cxf.jaxrs.client.WebClient does not seem to look for a
>> ResponseExceptionMapper. The doInvoke() method (around line 885)
>> simply looks at the response status returned and throws an error for
> status > 300.
>> However, the org.apache.cxf.jaxrs.client. ClientProxyImpl has a
>> checkResponse method that actually checks for a custom mapper. The doc
>> seems to make me think that whether I'm using the WebClient or a
>> proxy, I should be able to deal with exceptions in the same way. Is
>> this supposed to be true?
>
> WebClient is not supposed to deal with ResponseExceptionMapper - its purpose
> is to facilitate the optional mapping of HTTP errors to Exception classes
> listed in proxy method signatures
>
> Sergey
>>
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>> Sent: Wednesday, October 15, 2014 4:06 PM
>> To: users@cxf.apache.org
>> Subject: Re: Trouble configuring custom ResponseExceptionMapper
>>
>> I'll double check tomorrow, but I believe we have the tests involving
>> ResponseExceptionMapper, the conversion to default exceptions only
>> happens if no matching ResponseExceptionMapper has been detected...
>>
>> Looks like a registration issue too... Any chance you can provide a
>> test case or may be debug into it ?
>>
>> Cheers, Sergey
>>
>> On 15/10/14 17:39, Curtis Garman wrote:
>>> I have a java 8, Spring 4.1.1, cxf 3.0.1 app where I am tring to
>>> implement a custom ResponseExceptionMapper for all exceptions
>>> returned to my rest client. When I start my application, everything
>>> starts fine. However even when I start the app with DEBUG logging
>>> turned on, I see nothing related to my exception mapper. To test the
>>> functionality, I am passing invalid creds to the rest service I'm
>>> consuming. According to my mapper, the 403 response should be
>>> converted to a custom AuthorizationException...however as can be seen
>>> from
>> my log, the 403 is being converted to a jaxrs ForbiddenException.
>>> Can anyone help me get things wired correctly? I noticed some of the
>>> interfaces changed between cxf 2.x and 3.x. Is there a different
>>> interface that I should be implementing? Implementing ExceptionMapper
>>> on the service provider side works just fine.
>>>
>>>
>>>
>>>
>>>
>>> package test.webservice.rest.exception;
>>>
>>>
>>>
>>> import javax.ws.rs.WebApplicationException;
>>>
>>> import javax.ws.rs.core.Response;
>>>
>>> import javax.ws.rs.ext.Provider;
>>>
>>>
>>>
>>> import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
>>>
>>> import org.slf4j.Logger;
>>>
>>> import org.slf4j.LoggerFactory;
>>>
>>> import org.springframework.stereotype.Component;
>>>
>>>
>>>
>>> @Provider
>>>
>>> @Component("exceptionMapper")
>>>
>>> public class CustomResponseExceptionMapper implements
>>> ResponseExceptionMapper<Exception> {
>>>
>>>
>>>
>>>        private static final Logger LOGGER =
>>> LoggerFactory.getLogger(CustomResponseExceptionMapper.class);
>>>
>>>
>>>
>>>        @Override
>>>
>>>        public Exception fromResponse(Response response) {
>>>
>>>            LOGGER.debug(String.format("Executing %s",
>>> CustomResponseExceptionMapper.class));
>>>
>>>            Response.Status status =
>>> Response.Status.fromStatusCode(response.getStatus());
>>>
>>>            LOGGER.debug(String.format("Status: %s",
>>> status.getStatusCode()));
>>>
>>>            switch (status) {
>>>
>>>                case BAD_REQUEST:
>>>
>>>                    throw new
>>> InvalidInputException(response.getHeaderString("exception"));
>>>
>>>                case UNAUTHORIZED:
>>>
>>>                    throw new
>>> AuthorizationException(response.getHeaderString("exception"));
>>>
>>>                case FORBIDDEN:
>>>
>>>                    throw new
>>> AuthorizationException(response.getHeaderString("exception"));
>>>
>>>                case NOT_FOUND:
>>>
>>>                    throw new
>>> EmptyResultDataAccessException(response.getHeaderString("exception"))
>>> ;
>>>
>>>                case CONFLICT:
>>>
>>>                    throw new
>>> DuplicateKeyException(response.getHeaderString("exception"));
>>>
>>>                default:
>>>
>>>                    throw new
>>> WebApplicationException(response.getHeaderString("exception"));
>>>
>>>            }
>>>
>>>        }
>>>
>>>
>>>
>>> }
>>>
>>>
>>>
>>>
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>>
>>> <beans xmlns="http://www.springframework.org/schema/beans"
>>>
>>>                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>
>>>
>>> xmlns:context="http://www.springframework.org/schema/context"
>>>
>>>                    xmlns:cxf="http://cxf.apache.org/core"
>>>
>>>                    xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client"
>>>
>>>                    xsi:schemaLocation="
>>>
>>>
>>> http://www.springframework.org/schema/beans
>>> http://www.springframework.org/schema/beans/spring-beans.xsd
>>>
>>>
>>> http://www.springframework.org/schema/context
>>> http://www.springframework.org/schema/context/spring-context.xsd
>>>
>>>                                   http://cxf.apache.org/core
>>> http://cxf.apache.org/schemas/core.xsd
>>>
>>>                                   http://cxf.apache.org/jaxrs-client
>>> http://cxf.apache.org/schemas/jaxrs-client.xsd">
>>>
>>>
>>>
>>>                    <import resource="classpath:META-INF/cxf/cxf.xml"/>
>>>
>>>                    <import
>>> resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
>>>
>>>
>>>
>>>                    <bean id="jsonProvider"
>>> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
>>>
>>>
>>>
>>>        <jaxrs-client:client id="albumClient"
>>>
>>>                    serviceClass="org.apache.cxf.jaxrs.client.WebClient"
>>>
>>>
>>> address="http://localhost:8080/rest-provider/services/album"
>>>
>>>                                    username="test"
>>>
>>>                                    password="test">
>>>
>>>                                    <jaxrs-client:headers>
>>>
>>>                                                    <entry key="Accept"
>>> value="application/xml"/>
>>>
>>>                                    </jaxrs-client:headers>
>>>
>>>                    <jaxrs-client:providers>
>>>
>>>                                                    <ref
>>> bean="requestFilter" />
>>>
>>>                                    <ref bean="jsonProvider" />
>>>
>>>                                    <ref bean="responseFilter" />
>>>
>>>                                                    <ref
>> bean="exceptionMapper"
>>> />
>>>
>>>                                    </jaxrs-client:providers>
>>>
>>>                    </jaxrs-client:client>
>>>
>>>
>>>
>>>                    <context:component-scan
>>> base-package="test.webservice.rest.exception" />
>>>
>>>        <context:component-scan
>>> base-package="test.webservice.rest.filter" />
>>>
>>>                    <context:component-scan
>>> base-package="test.webservice.rest.service" />
>>>
>>>
>>>
>>> </beans>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> HTTP Status 500 - Request processing failed; nested exception is
>>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>>
>>> type Exception report
>>>
>>> message Request processing failed; nested exception is
>>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>>
>>> description The server encountered an internal error that prevented
>>> it from fulfilling this request.
>>>
>>> exception
>>>
>>>
>>>
>>> org.springframework.web.util.NestedServletException: Request
>>> processing failed; nested exception is javax.ws.rs.ForbiddenException:
>>> HTTP 403 Forbidden
>>>
>>>
>>> org.springframework.web.servlet.FrameworkServlet.processRequest(Frame
>>> w
>>> orkSer
>>> vlet.java:973)
>>>
>>>
>>> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServl
>>> e
>>> t.java
>>> :852)
>>>
>>>
>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>>>
>>>
>>> org.springframework.web.servlet.FrameworkServlet.service(FrameworkSer
>>> v
>>> let.ja
>>> va:837)
>>>
>>>
>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>>>
>>>
>>> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterIntern
>>> a
>>> l(Shal
>>> lowEtagHeaderFilter.java:81)
>>>
>>>
>>> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR
>>> e
>>> questF
>>> ilter.java:107)
>>>
>>>
>>> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52
>>> )
>>>
>>> root cause
>>>
>>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>>
>>>
>>> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>>>
>>>
>>> sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
>>>
>>>
>>> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown
>>> Source)
>>>
>>>                    java.lang.reflect.Constructor.newInstance(Unknown
>>> Source)
>>>
>>>
>>> org.apache.cxf.jaxrs.client.AbstractClient.convertToWebApplicationExc
>>> e
>>> ption(
>>> AbstractClient.java:478)
>>>
>>>
>>> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:886)
>>>
>>>
>>> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:854)
>>>
>>>
>>>
>>
> org.apache.cxf.jaxrs.client.WebClient.invokeAndGetCollection(WebClient.java:
>>> 513)
>>>
>>>
>>> org.apache.cxf.jaxrs.client.WebClient.getCollection(WebClient.java:58
>>> 9
>>> )
>>>
>>>
>>> test.webservice.rest.service.SimpleAlbumService.findAlbums(SimpleAlbu
>>> m
>>> Servic
>>> e.java:28)
>>>
>>>
>>> test.webservice.rest.servlet.AlbumController.list(AlbumController.jav
>>> a
>>> :27)
>>>
>>>                    sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>>> Method)
>>>
>>>                    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown
>>> Source)
>>>
>>>
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
>>> Source)
>>>
>>>                    java.lang.reflect.Method.invoke(Unknown Source)
>>>
>>>
>>> org.springframework.web.method.support.InvocableHandlerMethod.invoke(
>>> I
>>> nvocab
>>> leHandlerMethod.java:215)
>>>
>>>
>>> org.springframework.web.method.support.InvocableHandlerMethod.invokeF
>>> o
>>> rReque
>>> st(InvocableHandlerMethod.java:132)
>>>
>>>
>>> org.springframework.web.servlet.mvc.method.annotation.ServletInvocabl
>>> e
>>> Handle
>>> rMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
>>>
>>>
>>> org.springframework.web.servlet.mvc.method.annotation.RequestMappingH
>>> a
>>> ndlerA
>>> dapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
>>>
>>>
>>> org.springframework.web.servlet.mvc.method.annotation.RequestMappingH
>>> a
>>> ndlerA
>>> dapter.handleInternal(RequestMappingHandlerAdapter.java:721)
>>>
>>>
>>> org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapt
>>> e
>>> r.hand
>>> le(AbstractHandlerMethodAdapter.java:83)
>>>
>>>
>>> org.springframework.web.servlet.DispatcherServlet.doDispatch(Dispatch
>>> e
>>> rServl
>>> et.java:943)
>>>
>>>
>>> org.springframework.web.servlet.DispatcherServlet.doService(Dispatche
>>> r
>>> Servle
>>> t.java:877)
>>>
>>>
>>> org.springframework.web.servlet.FrameworkServlet.processRequest(Frame
>>> w
>>> orkSer
>>> vlet.java:961)
>>>
>>>
>>> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServl
>>> e
>>> t.java
>>> :852)
>>>
>>>
>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>>>
>>>
>>> org.springframework.web.servlet.FrameworkServlet.service(FrameworkSer
>>> v
>>> let.ja
>>> va:837)
>>>
>>>
>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>>>
>>>
>>> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterIntern
>>> a
>>> l(Shal
>>> lowEtagHeaderFilter.java:81)
>>>
>>>
>>> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR
>>> e
>>> questF
>>> ilter.java:107)
>>>
>>>
>>> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52
>>> )
>>>
>>>
>>
>>
>>
>
>


RE: Trouble configuring custom ResponseExceptionMapper

Posted by Curtis Garman <cu...@gmail.com>.
Hmm...so I guess what I'm looking for is a way to define a sort of global
way to map status codes to exceptions so that I don't need to duplicate my
same try/catch logic around every client call. Aside from the
ResponseExceptionMapper, is there any way to do this for WebClient?

-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozkin@gmail.com] 
Sent: Thursday, October 16, 2014 11:23 AM
To: users@cxf.apache.org
Subject: Re: Trouble configuring custom ResponseExceptionMapper

On 16/10/14 17:04, Curtis Garman wrote:
> I did a little debugging and have discovered that 
> org.apache.cxf.jaxrs.client.WebClient does not seem to look for a 
> ResponseExceptionMapper. The doInvoke() method (around line 885) 
> simply looks at the response status returned and throws an error for
status > 300.
> However, the org.apache.cxf.jaxrs.client. ClientProxyImpl has a 
> checkResponse method that actually checks for a custom mapper. The doc 
> seems to make me think that whether I'm using the WebClient or a 
> proxy, I should be able to deal with exceptions in the same way. Is 
> this supposed to be true?

WebClient is not supposed to deal with ResponseExceptionMapper - its purpose
is to facilitate the optional mapping of HTTP errors to Exception classes
listed in proxy method signatures

Sergey
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: Wednesday, October 15, 2014 4:06 PM
> To: users@cxf.apache.org
> Subject: Re: Trouble configuring custom ResponseExceptionMapper
>
> I'll double check tomorrow, but I believe we have the tests involving 
> ResponseExceptionMapper, the conversion to default exceptions only 
> happens if no matching ResponseExceptionMapper has been detected...
>
> Looks like a registration issue too... Any chance you can provide a 
> test case or may be debug into it ?
>
> Cheers, Sergey
>
> On 15/10/14 17:39, Curtis Garman wrote:
>> I have a java 8, Spring 4.1.1, cxf 3.0.1 app where I am tring to 
>> implement a custom ResponseExceptionMapper for all exceptions 
>> returned to my rest client. When I start my application, everything 
>> starts fine. However even when I start the app with DEBUG logging 
>> turned on, I see nothing related to my exception mapper. To test the 
>> functionality, I am passing invalid creds to the rest service I'm 
>> consuming. According to my mapper, the 403 response should be 
>> converted to a custom AuthorizationException...however as can be seen 
>> from
> my log, the 403 is being converted to a jaxrs ForbiddenException.
>> Can anyone help me get things wired correctly? I noticed some of the 
>> interfaces changed between cxf 2.x and 3.x. Is there a different 
>> interface that I should be implementing? Implementing ExceptionMapper 
>> on the service provider side works just fine.
>>
>>
>>
>>
>>
>> package test.webservice.rest.exception;
>>
>>
>>
>> import javax.ws.rs.WebApplicationException;
>>
>> import javax.ws.rs.core.Response;
>>
>> import javax.ws.rs.ext.Provider;
>>
>>
>>
>> import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
>>
>> import org.slf4j.Logger;
>>
>> import org.slf4j.LoggerFactory;
>>
>> import org.springframework.stereotype.Component;
>>
>>
>>
>> @Provider
>>
>> @Component("exceptionMapper")
>>
>> public class CustomResponseExceptionMapper implements 
>> ResponseExceptionMapper<Exception> {
>>
>>
>>
>>       private static final Logger LOGGER = 
>> LoggerFactory.getLogger(CustomResponseExceptionMapper.class);
>>
>>
>>
>>       @Override
>>
>>       public Exception fromResponse(Response response) {
>>
>>           LOGGER.debug(String.format("Executing %s", 
>> CustomResponseExceptionMapper.class));
>>
>>           Response.Status status =
>> Response.Status.fromStatusCode(response.getStatus());
>>
>>           LOGGER.debug(String.format("Status: %s", 
>> status.getStatusCode()));
>>
>>           switch (status) {
>>
>>               case BAD_REQUEST:
>>
>>                   throw new
>> InvalidInputException(response.getHeaderString("exception"));
>>
>>               case UNAUTHORIZED:
>>
>>                   throw new
>> AuthorizationException(response.getHeaderString("exception"));
>>
>>               case FORBIDDEN:
>>
>>                   throw new
>> AuthorizationException(response.getHeaderString("exception"));
>>
>>               case NOT_FOUND:
>>
>>                   throw new
>> EmptyResultDataAccessException(response.getHeaderString("exception"))
>> ;
>>
>>               case CONFLICT:
>>
>>                   throw new
>> DuplicateKeyException(response.getHeaderString("exception"));
>>
>>               default:
>>
>>                   throw new
>> WebApplicationException(response.getHeaderString("exception"));
>>
>>           }
>>
>>       }
>>
>>
>>
>> }
>>
>>
>>
>>
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>>
>> <beans xmlns="http://www.springframework.org/schema/beans"
>>
>>                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>
>>
>> xmlns:context="http://www.springframework.org/schema/context"
>>
>>                   xmlns:cxf="http://cxf.apache.org/core"
>>
>>                   xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client"
>>
>>                   xsi:schemaLocation="
>>
>>
>> http://www.springframework.org/schema/beans
>> http://www.springframework.org/schema/beans/spring-beans.xsd
>>
>>
>> http://www.springframework.org/schema/context
>> http://www.springframework.org/schema/context/spring-context.xsd
>>
>>                                  http://cxf.apache.org/core 
>> http://cxf.apache.org/schemas/core.xsd
>>
>>                                  http://cxf.apache.org/jaxrs-client
>> http://cxf.apache.org/schemas/jaxrs-client.xsd">
>>
>>
>>
>>                   <import resource="classpath:META-INF/cxf/cxf.xml"/>
>>
>>                   <import
>> resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
>>
>>
>>
>>                   <bean id="jsonProvider"
>> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
>>
>>
>>
>>       <jaxrs-client:client id="albumClient"
>>
>>                   serviceClass="org.apache.cxf.jaxrs.client.WebClient"
>>
>>
>> address="http://localhost:8080/rest-provider/services/album"
>>
>>                                   username="test"
>>
>>                                   password="test">
>>
>>                                   <jaxrs-client:headers>
>>
>>                                                   <entry key="Accept"
>> value="application/xml"/>
>>
>>                                   </jaxrs-client:headers>
>>
>>                   <jaxrs-client:providers>
>>
>>                                                   <ref 
>> bean="requestFilter" />
>>
>>                                   <ref bean="jsonProvider" />
>>
>>                                   <ref bean="responseFilter" />
>>
>>                                                   <ref
> bean="exceptionMapper"
>> />
>>
>>                                   </jaxrs-client:providers>
>>
>>                   </jaxrs-client:client>
>>
>>
>>
>>                   <context:component-scan 
>> base-package="test.webservice.rest.exception" />
>>
>>       <context:component-scan
>> base-package="test.webservice.rest.filter" />
>>
>>                   <context:component-scan 
>> base-package="test.webservice.rest.service" />
>>
>>
>>
>> </beans>
>>
>>
>>
>>
>>
>>
>>
>> HTTP Status 500 - Request processing failed; nested exception is
>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>
>> type Exception report
>>
>> message Request processing failed; nested exception is
>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>
>> description The server encountered an internal error that prevented 
>> it from fulfilling this request.
>>
>> exception
>>
>>
>>
>> org.springframework.web.util.NestedServletException: Request 
>> processing failed; nested exception is javax.ws.rs.ForbiddenException:
>> HTTP 403 Forbidden
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.processRequest(Frame
>> w
>> orkSer
>> vlet.java:973)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServl
>> e
>> t.java
>> :852)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.service(FrameworkSer
>> v
>> let.ja
>> va:837)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>>
>>
>> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterIntern
>> a
>> l(Shal
>> lowEtagHeaderFilter.java:81)
>>
>>
>> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR
>> e
>> questF
>> ilter.java:107)
>>
>>
>> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52
>> )
>>
>> root cause
>>
>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>
>>
>> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>>
>>
>> sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
>>
>>
>> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown
>> Source)
>>
>>                   java.lang.reflect.Constructor.newInstance(Unknown
>> Source)
>>
>>
>> org.apache.cxf.jaxrs.client.AbstractClient.convertToWebApplicationExc
>> e
>> ption(
>> AbstractClient.java:478)
>>
>>
>> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:886)
>>
>>
>> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:854)
>>
>>
>>
>
org.apache.cxf.jaxrs.client.WebClient.invokeAndGetCollection(WebClient.java:
>> 513)
>>
>>
>> org.apache.cxf.jaxrs.client.WebClient.getCollection(WebClient.java:58
>> 9
>> )
>>
>>
>> test.webservice.rest.service.SimpleAlbumService.findAlbums(SimpleAlbu
>> m
>> Servic
>> e.java:28)
>>
>>
>> test.webservice.rest.servlet.AlbumController.list(AlbumController.jav
>> a
>> :27)
>>
>>                   sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>> Method)
>>
>>                   sun.reflect.NativeMethodAccessorImpl.invoke(Unknown
>> Source)
>>
>>
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
>> Source)
>>
>>                   java.lang.reflect.Method.invoke(Unknown Source)
>>
>>
>> org.springframework.web.method.support.InvocableHandlerMethod.invoke(
>> I
>> nvocab
>> leHandlerMethod.java:215)
>>
>>
>> org.springframework.web.method.support.InvocableHandlerMethod.invokeF
>> o
>> rReque
>> st(InvocableHandlerMethod.java:132)
>>
>>
>> org.springframework.web.servlet.mvc.method.annotation.ServletInvocabl
>> e
>> Handle
>> rMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
>>
>>
>> org.springframework.web.servlet.mvc.method.annotation.RequestMappingH
>> a
>> ndlerA
>> dapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
>>
>>
>> org.springframework.web.servlet.mvc.method.annotation.RequestMappingH
>> a
>> ndlerA
>> dapter.handleInternal(RequestMappingHandlerAdapter.java:721)
>>
>>
>> org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapt
>> e
>> r.hand
>> le(AbstractHandlerMethodAdapter.java:83)
>>
>>
>> org.springframework.web.servlet.DispatcherServlet.doDispatch(Dispatch
>> e
>> rServl
>> et.java:943)
>>
>>
>> org.springframework.web.servlet.DispatcherServlet.doService(Dispatche
>> r
>> Servle
>> t.java:877)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.processRequest(Frame
>> w
>> orkSer
>> vlet.java:961)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServl
>> e
>> t.java
>> :852)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.service(FrameworkSer
>> v
>> let.ja
>> va:837)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>>
>>
>> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterIntern
>> a
>> l(Shal
>> lowEtagHeaderFilter.java:81)
>>
>>
>> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR
>> e
>> questF
>> ilter.java:107)
>>
>>
>> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52
>> )
>>
>>
>
>
>



Re: Trouble configuring custom ResponseExceptionMapper

Posted by Sergey Beryozkin <sb...@gmail.com>.
On 16/10/14 17:04, Curtis Garman wrote:
> I did a little debugging and have discovered that
> org.apache.cxf.jaxrs.client.WebClient does not seem to look for a
> ResponseExceptionMapper. The doInvoke() method (around line 885) simply
> looks at the response status returned and throws an error for status > 300.
> However, the org.apache.cxf.jaxrs.client. ClientProxyImpl has a
> checkResponse method that actually checks for a custom mapper. The doc seems
> to make me think that whether I'm using the WebClient or a proxy, I should
> be able to deal with exceptions in the same way. Is this supposed to be
> true?

WebClient is not supposed to deal with ResponseExceptionMapper - its 
purpose is to facilitate the optional mapping of HTTP errors to 
Exception classes listed in proxy method signatures

Sergey
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: Wednesday, October 15, 2014 4:06 PM
> To: users@cxf.apache.org
> Subject: Re: Trouble configuring custom ResponseExceptionMapper
>
> I'll double check tomorrow, but I believe we have the tests involving
> ResponseExceptionMapper, the conversion to default exceptions only happens
> if no matching ResponseExceptionMapper has been detected...
>
> Looks like a registration issue too... Any chance you can provide a test
> case or may be debug into it ?
>
> Cheers, Sergey
>
> On 15/10/14 17:39, Curtis Garman wrote:
>> I have a java 8, Spring 4.1.1, cxf 3.0.1 app where I am tring to
>> implement a custom ResponseExceptionMapper for all exceptions returned
>> to my rest client. When I start my application, everything starts
>> fine. However even when I start the app with DEBUG logging turned on,
>> I see nothing related to my exception mapper. To test the
>> functionality, I am passing invalid creds to the rest service I'm
>> consuming. According to my mapper, the 403 response should be
>> converted to a custom AuthorizationException...however as can be seen from
> my log, the 403 is being converted to a jaxrs ForbiddenException.
>> Can anyone help me get things wired correctly? I noticed some of the
>> interfaces changed between cxf 2.x and 3.x. Is there a different
>> interface that I should be implementing? Implementing ExceptionMapper
>> on the service provider side works just fine.
>>
>>
>>
>>
>>
>> package test.webservice.rest.exception;
>>
>>
>>
>> import javax.ws.rs.WebApplicationException;
>>
>> import javax.ws.rs.core.Response;
>>
>> import javax.ws.rs.ext.Provider;
>>
>>
>>
>> import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
>>
>> import org.slf4j.Logger;
>>
>> import org.slf4j.LoggerFactory;
>>
>> import org.springframework.stereotype.Component;
>>
>>
>>
>> @Provider
>>
>> @Component("exceptionMapper")
>>
>> public class CustomResponseExceptionMapper implements
>> ResponseExceptionMapper<Exception> {
>>
>>
>>
>>       private static final Logger LOGGER =
>> LoggerFactory.getLogger(CustomResponseExceptionMapper.class);
>>
>>
>>
>>       @Override
>>
>>       public Exception fromResponse(Response response) {
>>
>>           LOGGER.debug(String.format("Executing %s",
>> CustomResponseExceptionMapper.class));
>>
>>           Response.Status status =
>> Response.Status.fromStatusCode(response.getStatus());
>>
>>           LOGGER.debug(String.format("Status: %s",
>> status.getStatusCode()));
>>
>>           switch (status) {
>>
>>               case BAD_REQUEST:
>>
>>                   throw new
>> InvalidInputException(response.getHeaderString("exception"));
>>
>>               case UNAUTHORIZED:
>>
>>                   throw new
>> AuthorizationException(response.getHeaderString("exception"));
>>
>>               case FORBIDDEN:
>>
>>                   throw new
>> AuthorizationException(response.getHeaderString("exception"));
>>
>>               case NOT_FOUND:
>>
>>                   throw new
>> EmptyResultDataAccessException(response.getHeaderString("exception"));
>>
>>               case CONFLICT:
>>
>>                   throw new
>> DuplicateKeyException(response.getHeaderString("exception"));
>>
>>               default:
>>
>>                   throw new
>> WebApplicationException(response.getHeaderString("exception"));
>>
>>           }
>>
>>       }
>>
>>
>>
>> }
>>
>>
>>
>>
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>>
>> <beans xmlns="http://www.springframework.org/schema/beans"
>>
>>                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>
>>
>> xmlns:context="http://www.springframework.org/schema/context"
>>
>>                   xmlns:cxf="http://cxf.apache.org/core"
>>
>>                   xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client"
>>
>>                   xsi:schemaLocation="
>>
>>
>> http://www.springframework.org/schema/beans
>> http://www.springframework.org/schema/beans/spring-beans.xsd
>>
>>
>> http://www.springframework.org/schema/context
>> http://www.springframework.org/schema/context/spring-context.xsd
>>
>>                                  http://cxf.apache.org/core
>> http://cxf.apache.org/schemas/core.xsd
>>
>>                                  http://cxf.apache.org/jaxrs-client
>> http://cxf.apache.org/schemas/jaxrs-client.xsd">
>>
>>
>>
>>                   <import resource="classpath:META-INF/cxf/cxf.xml"/>
>>
>>                   <import
>> resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
>>
>>
>>
>>                   <bean id="jsonProvider"
>> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
>>
>>
>>
>>       <jaxrs-client:client id="albumClient"
>>
>>                   serviceClass="org.apache.cxf.jaxrs.client.WebClient"
>>
>>
>> address="http://localhost:8080/rest-provider/services/album"
>>
>>                                   username="test"
>>
>>                                   password="test">
>>
>>                                   <jaxrs-client:headers>
>>
>>                                                   <entry key="Accept"
>> value="application/xml"/>
>>
>>                                   </jaxrs-client:headers>
>>
>>                   <jaxrs-client:providers>
>>
>>                                                   <ref
>> bean="requestFilter" />
>>
>>                                   <ref bean="jsonProvider" />
>>
>>                                   <ref bean="responseFilter" />
>>
>>                                                   <ref
> bean="exceptionMapper"
>> />
>>
>>                                   </jaxrs-client:providers>
>>
>>                   </jaxrs-client:client>
>>
>>
>>
>>                   <context:component-scan
>> base-package="test.webservice.rest.exception" />
>>
>>       <context:component-scan
>> base-package="test.webservice.rest.filter" />
>>
>>                   <context:component-scan
>> base-package="test.webservice.rest.service" />
>>
>>
>>
>> </beans>
>>
>>
>>
>>
>>
>>
>>
>> HTTP Status 500 - Request processing failed; nested exception is
>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>
>> type Exception report
>>
>> message Request processing failed; nested exception is
>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>
>> description The server encountered an internal error that prevented it
>> from fulfilling this request.
>>
>> exception
>>
>>
>>
>> org.springframework.web.util.NestedServletException: Request
>> processing failed; nested exception is javax.ws.rs.ForbiddenException:
>> HTTP 403 Forbidden
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.processRequest(Framew
>> orkSer
>> vlet.java:973)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServle
>> t.java
>> :852)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.service(FrameworkServ
>> let.ja
>> va:837)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>>
>>
>> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInterna
>> l(Shal
>> lowEtagHeaderFilter.java:81)
>>
>>
>> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRe
>> questF
>> ilter.java:107)
>>
>>
>> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
>>
>> root cause
>>
>> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>>
>>
>> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>>
>>
>> sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
>>
>>
>> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown
>> Source)
>>
>>                   java.lang.reflect.Constructor.newInstance(Unknown
>> Source)
>>
>>
>> org.apache.cxf.jaxrs.client.AbstractClient.convertToWebApplicationExce
>> ption(
>> AbstractClient.java:478)
>>
>>
>> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:886)
>>
>>
>> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:854)
>>
>>
>>
> org.apache.cxf.jaxrs.client.WebClient.invokeAndGetCollection(WebClient.java:
>> 513)
>>
>>
>> org.apache.cxf.jaxrs.client.WebClient.getCollection(WebClient.java:589
>> )
>>
>>
>> test.webservice.rest.service.SimpleAlbumService.findAlbums(SimpleAlbum
>> Servic
>> e.java:28)
>>
>>
>> test.webservice.rest.servlet.AlbumController.list(AlbumController.java
>> :27)
>>
>>                   sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>> Method)
>>
>>                   sun.reflect.NativeMethodAccessorImpl.invoke(Unknown
>> Source)
>>
>>
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
>> Source)
>>
>>                   java.lang.reflect.Method.invoke(Unknown Source)
>>
>>
>> org.springframework.web.method.support.InvocableHandlerMethod.invoke(I
>> nvocab
>> leHandlerMethod.java:215)
>>
>>
>> org.springframework.web.method.support.InvocableHandlerMethod.invokeFo
>> rReque
>> st(InvocableHandlerMethod.java:132)
>>
>>
>> org.springframework.web.servlet.mvc.method.annotation.ServletInvocable
>> Handle
>> rMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
>>
>>
>> org.springframework.web.servlet.mvc.method.annotation.RequestMappingHa
>> ndlerA
>> dapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
>>
>>
>> org.springframework.web.servlet.mvc.method.annotation.RequestMappingHa
>> ndlerA
>> dapter.handleInternal(RequestMappingHandlerAdapter.java:721)
>>
>>
>> org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapte
>> r.hand
>> le(AbstractHandlerMethodAdapter.java:83)
>>
>>
>> org.springframework.web.servlet.DispatcherServlet.doDispatch(Dispatche
>> rServl
>> et.java:943)
>>
>>
>> org.springframework.web.servlet.DispatcherServlet.doService(Dispatcher
>> Servle
>> t.java:877)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.processRequest(Framew
>> orkSer
>> vlet.java:961)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServle
>> t.java
>> :852)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>>
>>
>> org.springframework.web.servlet.FrameworkServlet.service(FrameworkServ
>> let.ja
>> va:837)
>>
>>
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>>
>>
>> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInterna
>> l(Shal
>> lowEtagHeaderFilter.java:81)
>>
>>
>> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRe
>> questF
>> ilter.java:107)
>>
>>
>> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
>>
>>
>
>
>


RE: Trouble configuring custom ResponseExceptionMapper

Posted by Curtis Garman <cu...@gmail.com>.
I did a little debugging and have discovered that
org.apache.cxf.jaxrs.client.WebClient does not seem to look for a
ResponseExceptionMapper. The doInvoke() method (around line 885) simply
looks at the response status returned and throws an error for status > 300.
However, the org.apache.cxf.jaxrs.client. ClientProxyImpl has a
checkResponse method that actually checks for a custom mapper. The doc seems
to make me think that whether I'm using the WebClient or a proxy, I should
be able to deal with exceptions in the same way. Is this supposed to be
true?

-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozkin@gmail.com] 
Sent: Wednesday, October 15, 2014 4:06 PM
To: users@cxf.apache.org
Subject: Re: Trouble configuring custom ResponseExceptionMapper

I'll double check tomorrow, but I believe we have the tests involving
ResponseExceptionMapper, the conversion to default exceptions only happens
if no matching ResponseExceptionMapper has been detected...

Looks like a registration issue too... Any chance you can provide a test
case or may be debug into it ?

Cheers, Sergey

On 15/10/14 17:39, Curtis Garman wrote:
> I have a java 8, Spring 4.1.1, cxf 3.0.1 app where I am tring to 
> implement a custom ResponseExceptionMapper for all exceptions returned 
> to my rest client. When I start my application, everything starts 
> fine. However even when I start the app with DEBUG logging turned on, 
> I see nothing related to my exception mapper. To test the 
> functionality, I am passing invalid creds to the rest service I'm 
> consuming. According to my mapper, the 403 response should be 
> converted to a custom AuthorizationException...however as can be seen from
my log, the 403 is being converted to a jaxrs ForbiddenException.
> Can anyone help me get things wired correctly? I noticed some of the 
> interfaces changed between cxf 2.x and 3.x. Is there a different 
> interface that I should be implementing? Implementing ExceptionMapper 
> on the service provider side works just fine.
>
>
>
>
>
> package test.webservice.rest.exception;
>
>
>
> import javax.ws.rs.WebApplicationException;
>
> import javax.ws.rs.core.Response;
>
> import javax.ws.rs.ext.Provider;
>
>
>
> import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
>
> import org.slf4j.Logger;
>
> import org.slf4j.LoggerFactory;
>
> import org.springframework.stereotype.Component;
>
>
>
> @Provider
>
> @Component("exceptionMapper")
>
> public class CustomResponseExceptionMapper implements 
> ResponseExceptionMapper<Exception> {
>
>
>
>      private static final Logger LOGGER = 
> LoggerFactory.getLogger(CustomResponseExceptionMapper.class);
>
>
>
>      @Override
>
>      public Exception fromResponse(Response response) {
>
>          LOGGER.debug(String.format("Executing %s", 
> CustomResponseExceptionMapper.class));
>
>          Response.Status status =
> Response.Status.fromStatusCode(response.getStatus());
>
>          LOGGER.debug(String.format("Status: %s", 
> status.getStatusCode()));
>
>          switch (status) {
>
>              case BAD_REQUEST:
>
>                  throw new
> InvalidInputException(response.getHeaderString("exception"));
>
>              case UNAUTHORIZED:
>
>                  throw new
> AuthorizationException(response.getHeaderString("exception"));
>
>              case FORBIDDEN:
>
>                  throw new
> AuthorizationException(response.getHeaderString("exception"));
>
>              case NOT_FOUND:
>
>                  throw new
> EmptyResultDataAccessException(response.getHeaderString("exception"));
>
>              case CONFLICT:
>
>                  throw new
> DuplicateKeyException(response.getHeaderString("exception"));
>
>              default:
>
>                  throw new
> WebApplicationException(response.getHeaderString("exception"));
>
>          }
>
>      }
>
>
>
> }
>
>
>
>
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <beans xmlns="http://www.springframework.org/schema/beans"
>
>                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
>
> xmlns:context="http://www.springframework.org/schema/context"
>
>                  xmlns:cxf="http://cxf.apache.org/core"
>
>                  xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client"
>
>                  xsi:schemaLocation="
>
>                                  
> http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd
>
>                                 
> http://www.springframework.org/schema/context
> http://www.springframework.org/schema/context/spring-context.xsd
>
>                                 http://cxf.apache.org/core 
> http://cxf.apache.org/schemas/core.xsd
>
>                                 http://cxf.apache.org/jaxrs-client
> http://cxf.apache.org/schemas/jaxrs-client.xsd">
>
>
>
>                  <import resource="classpath:META-INF/cxf/cxf.xml"/>
>
>                  <import 
> resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
>
>
>
>                  <bean id="jsonProvider"
> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
>
>
>
>      <jaxrs-client:client id="albumClient"
>
>                  serviceClass="org.apache.cxf.jaxrs.client.WebClient"
>
>
> address="http://localhost:8080/rest-provider/services/album"
>
>                                  username="test"
>
>                                  password="test">
>
>                                  <jaxrs-client:headers>
>
>                                                  <entry key="Accept"
> value="application/xml"/>
>
>                                  </jaxrs-client:headers>
>
>                  <jaxrs-client:providers>
>
>                                                  <ref 
> bean="requestFilter" />
>
>                                  <ref bean="jsonProvider" />
>
>                                  <ref bean="responseFilter" />
>
>                                                  <ref
bean="exceptionMapper"
> />
>
>                                  </jaxrs-client:providers>
>
>                  </jaxrs-client:client>
>
>
>
>                  <context:component-scan 
> base-package="test.webservice.rest.exception" />
>
>      <context:component-scan 
> base-package="test.webservice.rest.filter" />
>
>                  <context:component-scan 
> base-package="test.webservice.rest.service" />
>
>
>
> </beans>
>
>
>
>
>
>
>
> HTTP Status 500 - Request processing failed; nested exception is
> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>
> type Exception report
>
> message Request processing failed; nested exception is
> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>
> description The server encountered an internal error that prevented it 
> from fulfilling this request.
>
> exception
>
>
>
> org.springframework.web.util.NestedServletException: Request 
> processing failed; nested exception is javax.ws.rs.ForbiddenException: 
> HTTP 403 Forbidden
>
>
> org.springframework.web.servlet.FrameworkServlet.processRequest(Framew
> orkSer
> vlet.java:973)
>
>
> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServle
> t.java
> :852)
>
>                  
> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>
>
> org.springframework.web.servlet.FrameworkServlet.service(FrameworkServ
> let.ja
> va:837)
>
>                  
> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>
>
> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInterna
> l(Shal
> lowEtagHeaderFilter.java:81)
>
>
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRe
> questF
> ilter.java:107)
>
>
> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
>
> root cause
>
> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>
>
> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>
>
> sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
>
>
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown 
> Source)
>
>                  java.lang.reflect.Constructor.newInstance(Unknown 
> Source)
>
>
> org.apache.cxf.jaxrs.client.AbstractClient.convertToWebApplicationExce
> ption(
> AbstractClient.java:478)
>
>
> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:886)
>
>
> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:854)
>
>
>
org.apache.cxf.jaxrs.client.WebClient.invokeAndGetCollection(WebClient.java:
> 513)
>
>
> org.apache.cxf.jaxrs.client.WebClient.getCollection(WebClient.java:589
> )
>
>
> test.webservice.rest.service.SimpleAlbumService.findAlbums(SimpleAlbum
> Servic
> e.java:28)
>
>
> test.webservice.rest.servlet.AlbumController.list(AlbumController.java
> :27)
>
>                  sun.reflect.NativeMethodAccessorImpl.invoke0(Native 
> Method)
>
>                  sun.reflect.NativeMethodAccessorImpl.invoke(Unknown 
> Source)
>
>                  
> sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
> Source)
>
>                  java.lang.reflect.Method.invoke(Unknown Source)
>
>
> org.springframework.web.method.support.InvocableHandlerMethod.invoke(I
> nvocab
> leHandlerMethod.java:215)
>
>
> org.springframework.web.method.support.InvocableHandlerMethod.invokeFo
> rReque
> st(InvocableHandlerMethod.java:132)
>
>
> org.springframework.web.servlet.mvc.method.annotation.ServletInvocable
> Handle
> rMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
>
>
> org.springframework.web.servlet.mvc.method.annotation.RequestMappingHa
> ndlerA
> dapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
>
>
> org.springframework.web.servlet.mvc.method.annotation.RequestMappingHa
> ndlerA
> dapter.handleInternal(RequestMappingHandlerAdapter.java:721)
>
>
> org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapte
> r.hand
> le(AbstractHandlerMethodAdapter.java:83)
>
>
> org.springframework.web.servlet.DispatcherServlet.doDispatch(Dispatche
> rServl
> et.java:943)
>
>
> org.springframework.web.servlet.DispatcherServlet.doService(Dispatcher
> Servle
> t.java:877)
>
>
> org.springframework.web.servlet.FrameworkServlet.processRequest(Framew
> orkSer
> vlet.java:961)
>
>
> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServle
> t.java
> :852)
>
>                  
> javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>
>
> org.springframework.web.servlet.FrameworkServlet.service(FrameworkServ
> let.ja
> va:837)
>
>                  
> javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>
>
> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInterna
> l(Shal
> lowEtagHeaderFilter.java:81)
>
>
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRe
> questF
> ilter.java:107)
>
>
> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
>
>




Re: Trouble configuring custom ResponseExceptionMapper

Posted by Sergey Beryozkin <sb...@gmail.com>.
I'll double check tomorrow, but I believe we have the tests involving 
ResponseExceptionMapper, the conversion to default exceptions only 
happens if no matching ResponseExceptionMapper has been detected...

Looks like a registration issue too... Any chance you can provide a test 
case or may be debug into it ?

Cheers, Sergey

On 15/10/14 17:39, Curtis Garman wrote:
> I have a java 8, Spring 4.1.1, cxf 3.0.1 app where I am tring to implement a
> custom ResponseExceptionMapper for all exceptions returned to my rest
> client. When I start my application, everything starts fine. However even
> when I start the app with DEBUG logging turned on, I see nothing related to
> my exception mapper. To test the functionality, I am passing invalid creds
> to the rest service I'm consuming. According to my mapper, the 403 response
> should be converted to a custom AuthorizationException...however as can be
> seen from my log, the 403 is being converted to a jaxrs ForbiddenException.
> Can anyone help me get things wired correctly? I noticed some of the
> interfaces changed between cxf 2.x and 3.x. Is there a different interface
> that I should be implementing? Implementing ExceptionMapper on the service
> provider side works just fine.
>
>
>
>
>
> package test.webservice.rest.exception;
>
>
>
> import javax.ws.rs.WebApplicationException;
>
> import javax.ws.rs.core.Response;
>
> import javax.ws.rs.ext.Provider;
>
>
>
> import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
>
> import org.slf4j.Logger;
>
> import org.slf4j.LoggerFactory;
>
> import org.springframework.stereotype.Component;
>
>
>
> @Provider
>
> @Component("exceptionMapper")
>
> public class CustomResponseExceptionMapper implements
> ResponseExceptionMapper<Exception> {
>
>
>
>      private static final Logger LOGGER =
> LoggerFactory.getLogger(CustomResponseExceptionMapper.class);
>
>
>
>      @Override
>
>      public Exception fromResponse(Response response) {
>
>          LOGGER.debug(String.format("Executing %s",
> CustomResponseExceptionMapper.class));
>
>          Response.Status status =
> Response.Status.fromStatusCode(response.getStatus());
>
>          LOGGER.debug(String.format("Status: %s", status.getStatusCode()));
>
>          switch (status) {
>
>              case BAD_REQUEST:
>
>                  throw new
> InvalidInputException(response.getHeaderString("exception"));
>
>              case UNAUTHORIZED:
>
>                  throw new
> AuthorizationException(response.getHeaderString("exception"));
>
>              case FORBIDDEN:
>
>                  throw new
> AuthorizationException(response.getHeaderString("exception"));
>
>              case NOT_FOUND:
>
>                  throw new
> EmptyResultDataAccessException(response.getHeaderString("exception"));
>
>              case CONFLICT:
>
>                  throw new
> DuplicateKeyException(response.getHeaderString("exception"));
>
>              default:
>
>                  throw new
> WebApplicationException(response.getHeaderString("exception"));
>
>          }
>
>      }
>
>
>
> }
>
>
>
>
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <beans xmlns="http://www.springframework.org/schema/beans"
>
>                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
>
> xmlns:context="http://www.springframework.org/schema/context"
>
>                  xmlns:cxf="http://cxf.apache.org/core"
>
>                  xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client"
>
>                  xsi:schemaLocation="
>
>                                  http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd
>
>                                 http://www.springframework.org/schema/context
> http://www.springframework.org/schema/context/spring-context.xsd
>
>                                 http://cxf.apache.org/core
> http://cxf.apache.org/schemas/core.xsd
>
>                                 http://cxf.apache.org/jaxrs-client
> http://cxf.apache.org/schemas/jaxrs-client.xsd">
>
>
>
>                  <import resource="classpath:META-INF/cxf/cxf.xml"/>
>
>                  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
>
>
>
>                  <bean id="jsonProvider"
> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
>
>
>
>      <jaxrs-client:client id="albumClient"
>
>                  serviceClass="org.apache.cxf.jaxrs.client.WebClient"
>
>
> address="http://localhost:8080/rest-provider/services/album"
>
>                                  username="test"
>
>                                  password="test">
>
>                                  <jaxrs-client:headers>
>
>                                                  <entry key="Accept"
> value="application/xml"/>
>
>                                  </jaxrs-client:headers>
>
>                  <jaxrs-client:providers>
>
>                                                  <ref bean="requestFilter" />
>
>                                  <ref bean="jsonProvider" />
>
>                                  <ref bean="responseFilter" />
>
>                                                  <ref bean="exceptionMapper"
> />
>
>                                  </jaxrs-client:providers>
>
>                  </jaxrs-client:client>
>
>
>
>                  <context:component-scan
> base-package="test.webservice.rest.exception" />
>
>      <context:component-scan base-package="test.webservice.rest.filter" />
>
>                  <context:component-scan
> base-package="test.webservice.rest.service" />
>
>
>
> </beans>
>
>
>
>
>
>
>
> HTTP Status 500 - Request processing failed; nested exception is
> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>
> type Exception report
>
> message Request processing failed; nested exception is
> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>
> description The server encountered an internal error that prevented it from
> fulfilling this request.
>
> exception
>
>
>
> org.springframework.web.util.NestedServletException: Request processing
> failed; nested exception is javax.ws.rs.ForbiddenException: HTTP 403
> Forbidden
>
>
> org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkSer
> vlet.java:973)
>
>
> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java
> :852)
>
>                  javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>
>
> org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.ja
> va:837)
>
>                  javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>
>
> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(Shal
> lowEtagHeaderFilter.java:81)
>
>
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestF
> ilter.java:107)
>
>
> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
>
> root cause
>
> javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
>
>
> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>
>
> sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
>
>
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
>
>                  java.lang.reflect.Constructor.newInstance(Unknown Source)
>
>
> org.apache.cxf.jaxrs.client.AbstractClient.convertToWebApplicationException(
> AbstractClient.java:478)
>
>
> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:886)
>
>
> org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:854)
>
>
> org.apache.cxf.jaxrs.client.WebClient.invokeAndGetCollection(WebClient.java:
> 513)
>
>
> org.apache.cxf.jaxrs.client.WebClient.getCollection(WebClient.java:589)
>
>
> test.webservice.rest.service.SimpleAlbumService.findAlbums(SimpleAlbumServic
> e.java:28)
>
>
> test.webservice.rest.servlet.AlbumController.list(AlbumController.java:27)
>
>                  sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>
>                  sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>
>                  sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
> Source)
>
>                  java.lang.reflect.Method.invoke(Unknown Source)
>
>
> org.springframework.web.method.support.InvocableHandlerMethod.invoke(Invocab
> leHandlerMethod.java:215)
>
>
> org.springframework.web.method.support.InvocableHandlerMethod.invokeForReque
> st(InvocableHandlerMethod.java:132)
>
>
> org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandle
> rMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
>
>
> org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA
> dapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
>
>
> org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA
> dapter.handleInternal(RequestMappingHandlerAdapter.java:721)
>
>
> org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.hand
> le(AbstractHandlerMethodAdapter.java:83)
>
>
> org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServl
> et.java:943)
>
>
> org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServle
> t.java:877)
>
>
> org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkSer
> vlet.java:961)
>
>
> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java
> :852)
>
>                  javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
>
>
> org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.ja
> va:837)
>
>                  javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
>
>
> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(Shal
> lowEtagHeaderFilter.java:81)
>
>
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestF
> ilter.java:107)
>
>
> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
>
>