JAX-RS如何序列化嵌入在公共包装器对象中的JSON对象,并在没有包装器的情况下进行反序列化

时间:2017-04-22 22:05:05

标签: java json jersey jackson jax-rs

我打算将JSON数据发送到我的JAX-RS端点,如下所示:

POST /myendpoint

{
  "field1": "something",
  "field2": "something else",
  "field3": 12345
}

然后当我检索一个对象时,我希望它包含在一个共同的包装器中:

GET /myendpoint

{
  "type": "MyEndpoint"
  "items": [
    {
      "item":     {
        "id": 1,
        "field1": "something",
        "field2": "something else",
        "field3": 12345
      },
      "link": "https://api.site.com/myendpoint/1"
    },
    {
      "item":     {
        "id": 2,
        "field1": "different",
        "field2": "different else",
        "field3": 67890
      },
      "link": "https://api.site.com/myendpoint/2"
    }
  ],
  "page_size": 10,
  "page": 1,
  "total": 2,
  "message": ""
}

GET /myendpoint/2

{
  "type": "MyEndpoint"
  "items": [
    {
      "item":     {
        "id": 2,
        "field1": "different",
        "field2": "different else",
        "field3": 67890
      },
      "link": "https://api.site.com/myendpoint/2"
    }
  ],
  "page_size": 10,
  "page": 1,
  "total": 1,
  "message": ""
}

我开始在泽西岛使用Jackson FasterXML进行自动序列化/反序列化,即:

@Provider
public class JsonObjectMapperProvider implements ContextResolver<ObjectMapper> {

    private final ObjectMapper objectMapper;

    public JsonObjectMapperProvider() {
        objectMapper = new ObjectMapper();
    }

    @Override
    public ObjectMapper getContext(final Class<?> type) {
        return objectMapper;
    }

}

然后在资源中:

@POST
@Consumes(MediaType.APPLICATION_JSON)
public void createMyEndpoint(MyEndpoint myEndpoint) {
    myEndpointDao.create(myEndpoint);
    // ...
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<MyEndpoint> createMyEndpoint() {
    // I'm not actually sure how to do this one yet!! but I include it for completeness
    return myEndpointDao.getAll();
}

@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public MyEndpoint createMyEndpoint(@PathParam("{id}") id) {
    return myEndpointDao.read(id);
}

这适用于未包含在包装器中的MyEndpoint对象,但是如何包含包装器?或者有更好的方法来做到这一点吗?

JSON的架构并不是一成不变的,如果其他东西更有意义,那么我就是全部耳朵。

1 个答案:

答案 0 :(得分:1)

在这里,我写了一些建议,我在考虑你的问题:

  1. 即使您正在处理POST方法,也会从您的方法中返回一些内容。这将使调用者知道请求状态。
  2. 而不是返回你的模型对象,我认为如果你的方法总是返回一个对象javax.ws.rs.core.Response
  3. 会更好
  4. 如果您担心序列化(我的意思是使用包装器),只需使用Response对象来序列化您的响应。例如,对于成功响应使用:Response.ok().entity(yourReturnObject).build(),这将几乎透明地处理序列化部分(您不需要处理objectMapper)。
  5. 这可能是方法的一个简单例子:

    @GET
    @Path("/{id}")
    @Produces({ "application/json" })
    public Response createMyEndpoint(@PathParam("id") String id) {
        try {
            return Response.ok().entity(myEndpointDao.read(id)).build();
        } catch (Exception e) {
           Response.status(500).entity(e.getMessage()).build();
        }
    }
    

    我还建议,为了让您的生活更简单,请查看swagger