Hi,
I'm trying to get a composition working in which I'm having trouble getting
my entity back from the Response even though the actual service request
seems to have succeeded. I'm using Jersey 2.5.1 and am using the client
API to have one service call another 2 services and then do some processing
based on the results of the 2 composed services.
I'm having no trouble getting the two services being composed to work,
marshaling the POJO service payload as JSON. If I call either service in a
browser they both work and spit out the appropriate JSON content.
Additionally, when I call them from within the composing service, it
appears that the calls have succeeded. Printing the Response via a logger
shows the following:
svcResponse: InboundJaxrsResponse{ClientResponse{method=GET, uri=
http://localhost:8080/v1.1/rs/foobar/1, status=200, reason=OK}}
Additionally, if I call (Response) svcResponse.hasEntity() I get a result
of true.
However, when I try to call readEntity(), I get a class cast exception:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast
to com.baz.domain.FooBar
A few details of my implementation that may be relevant are that we are
using an application class that subclasses ResourceConfig (without a
web.xml). This app class also uses the following package scanning call to
find our annotated classes:
packages("com.baz.rest");
The POJO domain model classes being returned are not in that package, as
the above snippet of stacktrace shows, but they are being marshaled to JSON
without issue, so I suspect that's not a problem.
I'm not registering any JSON provider, but have the following in my pom.xml
which seems to have enabled Jackson:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
I have also tried using the following in my pom.xml but it seems to make no
difference whether it's present or not:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
It is necessary for compilation if I explicitly register the
JacksonFeature, but seems to have no effect otherwise.
I'm using a simple unadorned client created in the composing service (the
one that is calling the other two services):
Client client = ClientBuilder.newClient();
I'm also creating a webTarget and an invocation in the following manner:
WebTarget webTarget = client.target("
http://localhost:8080/v1.1/rs");
Invocation.Builder invocationBuilder = webTarget
.path("foobar")
.path(foobarId.toString())
.request(MediaType.APPLICATION_JSON_TYPE);
Response svcResponse = invocationBuilder.get(Response.class);
I've tried explicitly enabling Jackson by adding the following call in my
application subclass:
register(JacksonFeature.class);
and adding a similar call in the client code like this:
Client client = ClientBuilder.newClient().register(JacksonFeature.class);
However, when I configure the server and client that way, the Jackson
databinding doesn't respect the @JsonIgnore annotations in our domain model
and suffers a stackoverflow error. Without that explicit configuration, I
get nice decent sized chunks of JSON which do respect the @JsonIgnore
annotations in our domain model. I've also tried to switch to the Moxy
JSON code by adding "register(MoxyJsonFeature.class);" to the application
class and calling "Client client =
ClientBuilder.newClient().register(MoxyJsonFeature.class);" in the client
code but this simply results in 500 errors even when calling the 2 composed
services in a browser. When I do no configuration in either the
application subclass or in the client code in the calling service as
originally shown above, I get the proper JSON representation in a browser
from each of the two composed services.
The problem occurs when I try to access the entity from the response. This
first call succeeds:
ResponseEnvelope<FooBar> envelope =
svcResponse.readEntity(ResponseEnvelope.class);
However, I get the class cast exception referencing a LinkedHashMap (?!?)
when I try the following call:
FooBar fooBar = envelope.getPayload();
Perhaps the problem is related to our envelope class that has a generic
domain class embedded in it? However, Jackson has no trouble marshaling
the ResponseEnvelope to JSON, so why would it fail in the opposite
direction?
I'm utterly confused (obvious? lol), any help would be *greatly*
appreciated!
--j