[ https://issues.apache.org/jira/browse/CXF-4912?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Parwiz Rezai updated CXF-4912: ------------------------------ Attachment: cxftest.zip full setup to build (maven or gradle) deploy to tomcat and run ClientTest as main entry point to run a client with wrong exception mapper selected shown. > cxf rest client always picks the first ResponseExceptionMapper for a method > with different exception throws > ----------------------------------------------------------------------------------------------------------- > > Key: CXF-4912 > URL: https://issues.apache.org/jira/browse/CXF-4912 > Project: CXF > Issue Type: Bug > Components: JAX-RS > Affects Versions: 2.7.3 > Environment: apache-tomcat-6.0.33, jdk1.6.0_34, spring 3.2.1.RELEASE, > jackson 2.1.4 > Reporter: Parwiz Rezai > Attachments: cxftest.zip > > > The selection for response mapper on client side will always pick the first > exception listed and invoke the mapper for that guy.. it will never > invoke Exception1ResponseMapper even though our exception is of type > Exception1.. > throws Exception2, Exception1 <-- this will always find a mapper for > Exception2 > first and use that even if our actual eexception is Exception1 in this case. > I think the code needs to lookup the mapper based on type as well > instead of generic first mapper found for that service. > I have two differnt exceptions: > {code:borderStyle=solid} > public class Exception1 extends Exception { > public Exception1() { } > public Exception1(String msg) { > super(msg); > } > } > public class Exception2 extends Exception { > public Exception2() {} > public Exception2(String msg) { > super(msg); > } > } > {code} > {code:title=Exception1ResponseMapper.java|borderStyle=solid} > import com.fasterxml.jackson.core.JsonParser; > import com.fasterxml.jackson.databind.MappingJsonFactory; > import java.io.InputStream; > import javax.ws.rs.core.Response; > import org.apache.cxf.jaxrs.client.ResponseExceptionMapper; > public class Exception1ResponseMapper implements > ResponseExceptionMapper<Exception1> { > @Override > public Exception1 fromResponse(Response response) { > try { > MappingJsonFactory factory = new MappingJsonFactory(); > JsonParser parser = factory.createJsonParser((InputStream) > response.getEntity()); > Exception1 exception = parser.readValueAs(Exception1.class); > return exception; > } catch (Exception ex) { > return new Exception1("Could not deserialize server side exception: > " + ex.getMessage()); > } > } > } > {code} > {code:title=Exception2ResponseMapper.java|borderStyle=solid} > import com.fasterxml.jackson.core.JsonParser; > import com.fasterxml.jackson.databind.MappingJsonFactory; > import java.io.InputStream; > import javax.ws.rs.core.Response; > import org.apache.cxf.jaxrs.client.ResponseExceptionMapper; > public class Exception2ResponseMapper implements > ResponseExceptionMapper<Exception2> { > @Override > public Exception2 fromResponse(Response response) { > try { > MappingJsonFactory factory = new MappingJsonFactory(); > JsonParser parser = factory.createJsonParser((InputStream) > response.getEntity()); > Exception2 exception = parser.readValueAs(Exception2.class); > // do some specific work for exception 2 only > return exception; > } catch (Exception ex) { > return new Exception2("Could not deserialize server side exception: > " + ex.getMessage()); > } > } > } > {code} > so suppose one mapper does something different than the other one. > now my service method: > {code:borderStyle=solid} > @Path("/cool") > @Consumes(MediaType.APPLICATION_JSON) > @Produces(MediaType.APPLICATION_JSON) > public interface MyService { > @GET > SomeCoolObject myMethod() throws Exception2, Exception1; > } > @Service("myService") > public class MyServiceImpl implements MyService { > public SomeCoolObject myMethod() throws Exception2, Exception1 { > throw new Exception1("hey this exception will still go exception 2 > mapper.. why?"); > } > } > {code} > {code:title=creating client proxy|borderStyle=solid} > List providers = new ArrayList<Object>(); > providers.add(new com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider()); > providers.add(new Exception1ResponseMapper()); > providers.add(new Exception2ResponseMapper()); > MyService serviceProxy = > JAXRSClientFactory.create("http://localhost:8080/", MyService.class, > providers); > try { > serviceProxy.myMethod(); > } catch(Exception e) { > // should get back Exception1 but no go > } > {code} > following is exception to response mappers on service side > {code:title=Exception mapping on server side|borderStyle=solid} > @Provider > public class Exception1AsResponseMapper implements > ExceptionMapper<Exception1> { > @Override > public Response toResponse(Exception1 exception) { > return Response.ok(exception, > MediaType.APPLICATION_JSON).status(Response.Status.BAD_REQUEST).build(); > } > } > @Provider > public class Exception2AsResponseMapper implements > ExceptionMapper<Exception2> { > @Override > public Response toResponse(Exception2 exception) { > return Response.ok(exception, > MediaType.APPLICATION_JSON).status(Response.Status.BAD_REQUEST).build(); > } > } > {code} > {code:xml|title=spring configs for cxf servlet} > <import resource="classpath:META-INF/cxf/cxf.xml" /> > <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> > <context:annotation-config/> > > <context:component-scan base-package="com.test"/> > <jaxrs:server id="services" address="/"> > <jaxrs:serviceBeans> > <ref bean="myService"/> > </jaxrs:serviceBeans> > <jaxrs:providers> > <bean > class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/> > <bean class="com.test.Exception1AsResponseMapper"/> > <bean class="com.test.Exception2AsResponseMapper"/> > </jaxrs:providers> > <jaxrs:extensionMappings> > <entry key="json" value="application/json" /> > </jaxrs:extensionMappings> > </jaxrs:server> > {code} > on the server side the right response mapper is invoked correctly based on > type of Exception thrown. -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira