heisa
heisa

Reputation: 854

How to create endpoint in Jersey for POST requests with or without body

I have an API created with Jersey

There's currently an endpoint to which users can make POST requests. There is no body required, as all the information is in the url.

@POST
@Path("entries")
@Produces(MEDIATYPE_JSON_AND_XML)
public Response createEntry(){
    ...
}

A new, empty, entry is created and the id is returned. Content-Type of the request doesn't matter, as there is no request body data.

Now it should also be possible to set specific fields of the new entry during the request, using FormData. For this request a body is necessary, and the Content-Type must be multipart/form-data.

So I've created a second function:

@POST
@Path("entries")
@Consumes("multipart/form-data");
@Produces(MEDIATYPE_JSON_AND_XML)
public Response createEntryWithParam(@FormDataParam('param') String param){
    ...
}

This second function works te send the parameter in the request. But by adding it, the first stops working.

Sending a request without Content-Type will throw a NullPointerException. Probably because the @Consumes triggers some kind of Content-Type-check, which fails.

Is there a way to have one endpoint accepting POST requests with or without request-body?

edit So, I would like to receive all multipart/form-data requests in the seconds function, and use the first as a kind of catch-all for other POST requests to that endpoint

Upvotes: 2

Views: 920

Answers (1)

heisa
heisa

Reputation: 854

Currently I have a work-around in place. If a POST request comes in without MediaType (Content-Type) or request-body, I automatically add an empty JSON object and set the Content-Type accordingly.

@Provider
public class ContentTypeRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext crc) throws IOException {

        if (crc.getMethod().equals("POST") && crc.getMediaType() == null && crc.getLength() == -1){
            crc.getHeaders().add("content-type", MediaType.APPLICATION_JSON);

            InputStream in = IOUtils.toInputStream("{}");
            crc.setEntityStream(in);
        }
    }
}

This works, but is kinda hacky in my opinion. I'm interested to know if there are better ways to achieve my desired result.

Upvotes: 4

Related Questions