How to create proper JAXB mapping to make Jersey deserialize process
I have a JSON response from WS:
[
{
"name": "Bobby",
"status": "single"
},
{
"name": "John",
"status": "married"
}
]
Here is my cover
@XmlRootElement(name = "users")
public class UserListWrapper {
private List<User> users;
@XmlElement(name = "user")
public List<User> getUsers() {
return users;
}
// getters and setters omitted
}
And the user class
@XmlRootElement
class User {
private String name;
private String status;
// getters and setters omitted
}
The problem is Jersey is trying to deserialize the response to my wrapper object. He says
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.jersey.test.UserListWrapper out of START_ARRAY token
Seams, something is wrong with my wrapper annotations. How can I fix them?
UPD
When i send
{
"user": [
{
"name": "Bob",
"status": "single"
},
{
"name": "Mike",
"status": "married"
}
]
}
everything works fine. But I need this format
[
{
"name": "Bobby",
"status": "single"
},
...
]
UPD
Jersey customer code
HttpAuthenticationFeature authenticationFeature = HttpAuthenticationFeature.basic("user", "secret");
Client client = ClientBuilder
.newClient()
.register(authenticationFeature)
.register(JacksonFeature.class);
WebTarget target = client.target("http://localhost:8080/server/");
UserListWrapper entity;
Response resp;
resp = target.queryParam("u", "info")
.path("/rest/users")
.request()
.accept(APPLICATION_JSON)
.get();
entity = resp.readEntity(UserListWrapper.class);
source to share
Forget the wrapper UserListWrapper
. List<User>
ideal for JSON ( []
) format . If you add a wrapper class, then yes, you need an additional JSON object layer ( {}
). It:
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createBook(List<User> users) {
supported just fine (at least with the Jackson you're using).
UPDATE
If the server response comes in as a JSON array, you can still deserialize it as List<User>
. for example
WebResource resource = client.resource("...");
List<User> users = resource.get(new GenericType<List<User>>(){});
See this related post
UPDATE 2
Since you are using the JAX-RS 2 API, you can use an overload readEntity
that takes an GenericType
argument as well
List<User> user = response.readEntity(new GenericType<List<User>>(){});
source to share