I have a JAXB-annotated employee class:
@XmlRootElement(name = "employee")
public class Employee {
private Integer id;
private String name;
...
@XmlElement(name = "id")
public int getId() {
return this.id;
}
... // setters and getters for name, equals, hashCode, toString
}
And a JAX-RS resource object (I'm using Jersey 1.12)
@GET
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/")
public List<Employee> findEmployees(
@QueryParam("name") String name,
@QueryParam("page") String pageNumber,
@QueryParam("pageSize") String pageSize) {
...
List<Employee> employees = employeeService.findEmployees(...);
return employees;
}
This endpoint works fine. I get
<employees>
<employee>
<id>2</id>
<name>Ana</name>
</employee>
</employees>
However, if I change the method to return a Response
object, and put the employee list in the response body, like this:
@GET
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/")
public Response findEmployees(
@QueryParam("name") String name,
@QueryParam("page") String pageNumber,
@QueryParam("pageSize") String pageSize) {
...
List<Employee> employees = employeeService.findEmployees(...);
return Response.ok().entity(employees).build();
}
the endpoint results in an HTTP 500 due to the following exception:
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.ArrayList, and Java type class java.util.ArrayList, and MIME media type application/xml was not found
In the first case, JAX-RS has obviously arranged for the proper message writer to kick in when returning a collection. It seems somewhat inconsistent that this doesn't happen when the collection is placed in the entity body. What approach can I take to get the automatic JAXB serialization of the list to happen when returning a response?
I know that I can
EmployeeList
classbut was wondering whether there is a nice way to use the Response
object and get the list to serialize without creating my own wrapper class.
You can wrap the List<Employee>
in an instance of GenericEntity
to preserve the type information:
You can use GenericEntity to send the collection in the Response. You must have included appropriate marshal/unmarshal library like moxy or jaxrs-jackson.
Below is the code :
@GET
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/")
public Response findEmployees(
@QueryParam("name") String name,
@QueryParam("page") String pageNumber,
@QueryParam("pageSize") String pageSize) {
...
List<Employee> employees = employeeService.findEmployees(...);
GenericEntity<List<Employee>> entity = new GenericEntity<List<Employee>>(Lists.newArrayList(employees))
return Response.ok().entity(entity).build();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With