1

I have JAX-RS 2.8.9 with Spring 4.3.4 app. I perform a very simple POST request to the following server code

@POST
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response test(MultivaluedMap<String, String> work) {
    return Response.ok(work.keySet().size()).build();
}

I test with curl:

 curl -i -X POST 'http://localhost:XXX/some/test' -d "param=value&param2=value2" -H "Content-Type: application/x-www-form-urlencoded"

I get the following warning

A servlet request to the URI http://localhost:XXX/some/test contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.

About which I found only cause that involve connection issues, apparently I don't have.

According to documentation this is the way to handle a case when we have a variable number of FormParams passed.

This works, though.

@POST
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response test(@FormParam("param") String param) {
    return Response.ok(param).build();
}

What can be the reason the multivalued map doesn't? Could it be some filtering? What is an alternative for unknown number of parameters?

UPDATE Is is due to a particularity of Jersey + Spring. A solution can be found in this answer.

Mateva
  • 786
  • 1
  • 8
  • 27
  • Are those parameters sharing the same data type? – dbl Oct 19 '18 at 15:13
  • Yes, they are string key-values; I just added an example of how I test in the description. – Mateva Oct 19 '18 at 15:17
  • 1
    You tagged [spring] in your question. How are you incorporating Spring into your application? There is a Spring servlet filter that consumes the request parameters. That may be the cause, and often is. – Paul Samsotha Oct 19 '18 at 16:08
  • 2
    There's a workaround where you can inject `@Context ContainerReqeust` into your method parameter and use `request.getProperty(InternalServerProperties.FORM_DECODED_PROPERTY)` and it will return [`Form`](https://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Form.html) – Paul Samsotha Oct 19 '18 at 16:21
  • Thanks, I tried those, but the problem was in the String request filter indeed. I linked an answer in the description. – Mateva Oct 22 '18 at 10:29
  • If you're using Spring Boot, here is [another workaround](https://stackoverflow.com/a/50423639/2587435) – Paul Samsotha Nov 03 '18 at 20:31

1 Answers1

0

What can be the reason the multivalued map doesn't? Could it be some filtering? What is an alternative for unknown number of parameters?

By default, it seems your JAX-RS implementation is detecting the form-input and reading/processing the body before it gets to your method. Have you tried:

@POST
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response test(Form workForm) {
    MultivaluedMap<String,String> work = workForm.asMap();
    return Response.ok(work.keySet().size()).build();
}

?

Form is a special JAX-RS class that encapsulates all the form parameters and should be usable as an input parameter to your method.

Darth Android
  • 3,437
  • 18
  • 19
  • Unfortunately, this did not work out. It turns out that Spring + Jersey have an issue, which resolution is found here. – Mateva Oct 22 '18 at 10:26