JAX-RS: Consuming JSON POST data without setting C

2019-07-09 21:59发布

I have implemented a REST service using Jersey that takes JSON POST data and creates an object from a POJO model. However, in order for this to work, I have to set the Content-Type to application/json (i.e., -H "Content-Type: application/json"). What I'd like is to be able to consume JSON POST request body without the user having to set the header, basically like Elasticsearch works:

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

Here's the relevant code:

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

2条回答
ら.Afraid
2楼-- · 2019-07-09 22:33

Figured it out. I'm now accepting "application/json" and "application/x-www-form-urlencoded" content types. Here's the code:

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

Though, after thinking for a bit, I probably should require the Content-Type header considering it contains a JSON request body, but that's another discussion entirely.

查看更多
做自己的国王
3楼-- · 2019-07-09 22:35

I faced a similar problem. Since in my opinion a well defined API - which doesn't share its endpoints with any other system - should not need to depend on clients specifying the correct Content-Type, I created a workaround. In this workaround, I add an annotation to those resource methods where I want Jersey to always attempt to read the input according to a server-defined Content-Type. Whenever this annotation is present, a ResourceFilter will override the Content-Type header in the request, to whatever is specified in the annotation.

I have detailed the process in my answer here.

查看更多
登录 后发表回答