web-dev-qa-db-ja.com

JAX-RS:Responseオブジェクトを返すときにコレクションを自動的にシリアル化する方法は?

JAXBアノテーション付きの従業員クラスがあります。

@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
}

そして、JAX-RSリソースオブジェクト(私は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;
}

このエンドポイントは正常に動作します。私は得る

<employees>
  <employee>
    <id>2</id>
    <name>Ana</name>
  </employee>
</employees>

ただし、Responseオブジェクトを返すようにメソッドを変更し、次のように従業員リストを応答本文に配置すると、

@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();
}

次の例外により、エンドポイントはHTTP 500になります。

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

最初のケースでは、JAX-RSはコレクションを返すときに適切なメッセージライターが起動するように明らかに調整しました。コレクションがエンティティボディに配置されている場合、これが発生しないことは多少矛盾しています。応答を返すときにリストの自動JAXBシリアル化を行うには、どのようなアプローチが可能ですか?

私はできることを知っています

  • リソースメソッドからリストを返すだけです
  • 別のEmployeeListクラスを作成する

しかし、Responseオブジェクトを使用してリストをシリアル化するための良い方法があるかどうか疑問に思っていましたwithout独自のラッパークラスを作成します。

17
Ray Toal

List<Employee>GenericEntityのインスタンスで、型情報を保持します。

26
bdoughan

GenericEntityを使用して、レスポンスでコレクションを送信できます。 moxyやjaxrs-jacksonなどの適切なマーシャル/アンマーシャルライブラリが含まれている必要があります。

以下はコードです:

    @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();
    }
3
Jitender Chahar