简体   繁体   中英

Jersey issue with unmarshalling responce entity with HashSet field

I have a problem with Jersey (2.13). I suppose that the problem related to un-marshalling mechanism. My User entity has a field - collection of Role entities. When I try to get it, I get an error.

Here is my classes

@XmlRootElement(name = "user")
public class User {

    private Set<Role> roleSet;

    // other fields omitted

    @XmlElementWrapper(name = "roles")
    @XmlElement(name = "role")
    public Set<Role> getRoleSet() { /* compiled code */ }

    // all other getters with simple JAXB annotations @XmlElement omitted    
}

Role

@XmlRootElement(name = "role")
public class ClientRole {
    private String name;
    private boolean active;
    private String id;

    @XmlElement(name = "name")
    public String getName() { /* compiled code */ }

    // all getters with JAXB annotations omitted

}

And my Jersey client code

HttpAuthenticationFeature authenticationFeature = HttpAuthenticationFeature.basic("freddy", "qwerty");    
        Client client = ClientBuilder
                .newClient()
                .register(authenticationFeature)
                .register(JacksonFeature.class);   

        WebTarget target = client.target("http://localhost:4444/server/");    

        Response resp = target
                .path("/api/users/freddy")
                .request()
                .accept(MediaType.APPLICATION_JSON)
                .get();   

        User entity = resp.readEntity(User.class);
        System.out.println(entity);

How can I fix that error? Or maybe I just forgot to register some new feature (for the new Jersey release 2.13)?

Exception in thread "main" javax.ws.rs.ProcessingException: Error reading entity from input stream.
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:866)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783)
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:399)
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108)
    at com.test.CreateUserExample.main(CreateUserExample.java:36)
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "roles" (class com.server.dto.auth.User), not marked as ignorable (6 known properties: "enabled", "statusId", "role", "username", "emailAddress", "password"])
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@34cdeda2; line: 1, column: 141] (through reference chain: com.server.dto.auth.User["roles"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)
    at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:671)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:771)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1297)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1275)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:247)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
    at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1233)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:677)
    at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:777)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:264)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:234)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)

UPDATE

Here is my dependencies

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.13</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.13</version>
</dependency>

UPDATE 2

String entity = resp.readEntity(String.class);

{"name":"Bob","enabled":true,"roles":[{"name":"ADMIN","active":false,"id":12313214},{"name":"USER","active":true,"id":45353}]}

The problem is that while serializing, you're probably using MOXy which adds the additional wrapping element ( roles in this case) which is not fully supported by Jackson.

You can either use MOXy for de-serialization at the client side

Client client = ClientBuilder
            .newClient()
            .register(authenticationFeature)
            .register(MoxyJsonFeature.class);

or to slightly change your model class so that JAXB serializer (MOXy) produces something that Jackson is able to de-serialize

@XmlElement(name = "roles")
public Set<Role> getRoleSet() {
    return roleSet;
}

Finally, you can let Jersey use Jackson on the server side by registering JacksonFeature :

@ApplicationPath("/")
public class TestApplication extends ResourceConfig {

    public TestApplication() {
        register(TestResource.class);
        register(JacksonFeature.class);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM