java - JAX-RS 如何反序列化嵌入在公共(public)包装器对象中的 JSON 对象以及在没有包装器的情况下反序列化

标签 java json jersey jackson jax-rs

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

POST/myendpoint

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

然后,当我检索一个对象时,我希望它包含在一个公共(public)包装器中:

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": ""
}

我开始在 Jersey 中使用 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. 即使您正在处理 POST 方法,也始终从您的方法中返回一些内容。这将使调用者了解请求状态。
  2. 我认为,如果您的方法始终返回一个对象,而不是返回模型对象,则更好 javax.ws.rs.core.Response
  3. 如果您担心序列化(我的意思是包装器的使用),只需使用 Response 对象来序列化您的响应。例如,对于成功响应,请使用:Response.ok().entity(yourReturnObject).build(),这将几乎透明地处理序列化部分(您不需要处理 objectMapper) 。

这可能是一个简单的方法示例:

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

关于java - JAX-RS 如何反序列化嵌入在公共(public)包装器对象中的 JSON 对象以及在没有包装器的情况下反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43565154/

相关文章:

java - 将频率转换为 java.time.Period 类型

Java 8 forEach Stream() 与旧的 forEach 循环

java - 尝试运行程序时仅在控制台中显示奇怪的错误

ios - 无法从 NSDictionary 和 JSON 获取值

json - 无法将 JSON 发布到 Jersey

java - 使用 BigDecimals 舍入区域

python - 在python中打印json文件的所有键

json - 基于数据的 ajv 条件模式验证

jersey - 以编程方式在 Jersey 中声明路径参数

java - 获取 Jersey 的邮政数据