cxf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Parwiz Rezai (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CXF-4912) cxf rest client always picks the first ResponseExceptionMapper for a method with different exception throws
Date Fri, 22 Mar 2013 06:59:15 GMT

     [ https://issues.apache.org/jira/browse/CXF-4912?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Parwiz Rezai updated CXF-4912:
------------------------------

    Environment: tomcat 6.33, java 1.6_34, spring 3.2.1.RELEASE, jackson 2.1.4  (was: tomcat
6.33, java 1.6_34, spring 3.2.1.RELEASE.)
    
> 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: tomcat 6.33, java 1.6_34, spring 3.2.1.RELEASE, jackson 2.1.4
>            Reporter: Parwiz Rezai
>
> 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}
> The selection for response mapper 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.. 
> I think the code needs to lookup the mapper based on type as well
> instead of generic first mapper found for that service.
> 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}
> 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

Mime
View raw message