json - 在 Jersey 服务中使用 JSON 对象

标签 json jersey

我一直在谷歌搜索,试图找出如何做到这一点:我有一个 Jersey REST 服务。调用 REST 服务的请求包含一个 JSON 对象。我的问题是,从 Jersey POST 方法实现中,我如何才能访问 HTTP 请求正文中的 JSON?

任何提示、技巧、示例代码的指针将不胜感激。

谢谢...

--史蒂夫

最佳答案

正如已经建议的那样,将 @Consumes Content-Type 更改为 text/plain 会起作用,但从 REST API 的角度来看,它似乎并不正确。

假设您的客户必须将 JSON 发布到您的 API,但需要将 Content-Type header 指定为 text/plain。在我看来它并不干净。简单来说,如果您的 API 接受 JSON,则请求 header 应指定 Content-Type: application/json

为了接受 JSON 但将其序列化为 String 对象而不是 POJO,您可以实现自定义 MessageBodyReader .这样做同样容易,而且您不必在 API 规范上妥协。

值得阅读 MessageBodyReader 的文档所以你确切地知道它是如何工作的。我就是这样做的:

步骤 1. 实现自定义 MessageBodyReader

@Provider
@Consumes("application/json")
public class CustomJsonReader<T> implements MessageBodyReader<T> {
  @Override
  public boolean isReadable(Class<?> type, Type genericType,
      Annotation[] annotations,MediaType mediaType) {
    return true;
  }

  @Override
  public T readFrom(Class<T> type, Type genericType, Annotation[] annotations,
      MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
      InputStream entityStream) throws IOException, WebApplicationException {

    /* Copy the input stream to String. Do this however you like.
     * Here I use Commons IOUtils.
     */
    StringWriter writer = new StringWriter();
    IOUtils.copy(entityStream, writer, "UTF-8");
    String json = writer.toString();

    /* if the input stream is expected to be deserialized into a String,
     * then just cast it
     */
    if (String.class == genericType)
      return type.cast(json);

    /* Otherwise, deserialize the JSON into a POJO type.
     * You can use whatever JSON library you want, here's
     * a simply example using GSON.
     */
    return new Gson().fromJson(json, genericType);
  }
}

上面的基本概念是检查输入流是否期望被转换为String(由Type genericType指定)。如果是这样,那么只需将 JSON 转换为指定的 type(这将是一个 String)。如果预期类型是某种 POJO,则使用 JSON 库(例如 Jackson 或 GS​​ON)将其反序列化为 POJO。

第二步,绑定(bind)你的MessageBodyReader

这取决于您使用的框架。我发现 Guice 和 Jersey 配合得很好。这是我如何绑定(bind)我的MessageBodyReader在古斯:

在我的JerseyServletModule我像这样绑定(bind)阅读器--

bind(CustomJsonReader.class).in(Scopes.SINGLETON);

上面的 CustomJsonReader 会将 JSON 有效负载反序列化为 POJO,如果您只是想要原始 JSON,还可以将 String 对象反序列化。

这样做的好处是它会接受Content-Type: application/json。换句话说,您的请求处理程序可以设置为使用 JSON,这似乎是正确的:

@POST
@Path("/stuff")
@Consumes("application/json") 
public void doStuff(String json) {
  /* do stuff with the json string */
  return;
}

关于json - 在 Jersey 服务中使用 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1662490/

相关文章:

java - 如何使用 fastxml jackson 忽略我没有的对象

c# - 获取 linq 列表中对象的百分比并将其映射到 JSON 的最佳方法是什么?

mysql - 如何在 MySQL 5.7 中的 JSON 数组中获取唯一/不同的元素

java - 为什么 jersey-bundle 1.17.1 中的 asm 提供了作用域?

java - 使用 Jersey 的 session Cookie

node.js - Webpack/babel 意外 token ,预期为 ";"

python - 如何从JSON文件python读取 "Côte d' Ivoire”

Java REST 服务在 POST 上生成 405

java - Jax-rs(Jersey) 在 POST 请求中使用 Json 对象数组

java - 使用 Jersey 客户端发送原始 XML?