【问题标题】:JAX-RS: Consuming JSON POST data without setting Content-Type header to application/jsonJAX-RS:使用 JSON POST 数据而不将 Content-Type 标头设置为 application/json
【发布时间】:2016-03-06 06:09:46
【问题描述】:

我已经使用 Jersey 实现了一个 REST 服务,它接受 JSON POST 数据并从 POJO 模型创建一个对象。但是,为了让它工作,我必须将 Content-Type 设置为 application/json(即-H "Content-Type: application/json")。我想要的是能够使用 JSON POST 请求正文而无需用户设置标头,基本上就像 Elasticsearch 一样:

POST /test_index/_search?search_type=count
{
   "aggs": {
      "nested_authors": {
         "nested": {
            "path": "authors"
         },
         "aggs": {
            "author_last_names": {
               "terms": {
                  "field": "authors.last_name"
               }
            }
         }
      }
   }
} 

以下是相关代码:

@POST
@Path("/person")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response postPerson(PostBody pb) {
    System.out.println(pb.getEmails());
}

【问题讨论】:

  • 问题在于 cURL,其默认内容类型为 application/x-www-form-urlencoded。因此,如果您不设置它,那将是您的端点无法处理的类型。我并没有真正玩过 elastcisearch,但我浏览的少数指南使用了 GET,并且数据是查询参数的一部分,这就是不需要 Content-Type 的原因
  • Elasticsearch 也允许使用 POST,因为一些客户端不允许使用 GET 的请求正文,并且使用 GET 发送请求正文没有意义(再说一遍,使用 POST 搜索也不行) ,所以双方确实都有问题)。我在我的问题中包含了一个来自 Elasticsearch 的 POST 示例,它包含一个 JSON 正文,使用 cURL,没有设置标题,并且运行良好。这基本上就是我想要效仿的。我查看了 cURL 的默认内容类型,并读到它是“文本/纯文本”,这似乎是错误的。我会在使用 APPLICATION_FORM_URLENCODED 时看看这是否有效。
  • 如果你想切换到使用带有查询参数的GET,或者带有表单参数的POST,如果你想使用POJO方法参数,你可能会发现this article很有用
  • 太棒了,感谢有关 cURL 默认内容类型的链接和方向。我已经回答了我自己的问题,它有效;但要查看链接,看看是否有更好的方法。巧合的是,我只是在阅读另一个问题的答案,并意识到这是您的答案。因此,还要感谢“我如何在 jersey2 中获得对 Jackson Object Mapper 的引用”的帮助:)

标签: java json rest jersey jax-rs


【解决方案1】:

我遇到了类似的问题。因为在我看来,一个定义良好的 API(它不与任何其他系统共享其端点)不应该依赖于指定正确 Content-Type 的客户端,所以我创建了一个解决方法。在此解决方法中,我向那些希望 Jersey 始终尝试根据服务器定义的 Content-Type 读取输入的资源方法添加注释。只要存在此注解,ResourceFilter 就会覆盖请求中的 Content-Type 标头,覆盖注解中指定的任何内容。

我已经在my answer here详细说明了这个过程。

【讨论】:

    【解决方案2】:

    想通了。我现在接受“application/json”和“application/x-www-form-urlencoded”内容类型。代码如下:

    @POST
    @Path("/person")
    @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_FORM_URLENCODED})
    @Produces(MediaType.APPLICATION_JSON)
    public Response postPerson(String body) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        PostBody pb = mapper.readValue(body, PostBody.class);
        System.out.println(pb.getEmails());
    }
    

    不过,经过一番思考,考虑到它包含 JSON 请求正文,我可能应该需要 Content-Type 标头,但这完全是另一个讨论。

    【讨论】:

      猜你喜欢
      • 2018-03-11
      • 2012-07-11
      • 2022-01-01
      • 1970-01-01
      • 2012-01-30
      • 2019-10-18
      • 2019-06-28
      • 2022-10-14
      • 2020-11-14
      相关资源
      最近更新 更多