42

I'm building a very simple REST API using Jersey, and I've got a warning in my log files that I'm not sure about.

WARNING: A servlet POST request, to the URI http://myserver/mycontext/myapi/users/12345?action=delete, 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.

My webapp only has the Jersey servlet defined, mapped to /myapi/*

How can I stop these warnings?

brabster
  • 42,504
  • 27
  • 146
  • 186

9 Answers9

14

For me the warning was showing for POST application/x-www-form-urlencoded. And I am using Spring Boot which has an HiddenHttpMethodFilter that does a getParameter before anything else... So I ended up doing this nasty override:

@Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new HiddenHttpMethodFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                    FilterChain filterChain) throws ServletException, IOException {
                if ("POST".equals(request.getMethod())
                        && request.getContentType().equals(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
                    filterChain.doFilter(request, response);
                } else {
                    super.doFilterInternal(request, response, filterChain);
                }
            }
        };
    }
javo
  • 181
  • 1
  • 4
  • Solved my problems too! (Is this a very special (stupid) setup we have that brought us into this issue, or why does other people not run into this issue?!? – Andreas Lundgren Sep 16 '16 at 09:37
  • I get this error when using Jersey MVC. If I switch to Spring MVC, this override is not necessary. – Andreas Lundgren Sep 16 '16 at 12:00
  • 2
    If you don't need the `HiddenHttpMethodFilter` at all, you could disabled it. See [here](https://stackoverflow.com/a/28428154/2049986) how to do that! – Jacob van Lingen Jun 07 '17 at 09:53
12

This message is meant to warn developers about the fact that the request entity body has been consumed, thus any other attempts to read the message body will fail.

It is safe to ignore the message or filter it out from the logs:

java.util.logging.Logger jerseyLogger =
        java.util.logging.Logger.getLogger(WebComponent.class.getName());
jerseyLogger.setFilter(new Filter() {
    @Override
    public boolean isLoggable(LogRecord record) {
        boolean isLoggable = true;
        if (record.getMessage().contains("Only resource methods using @FormParam")) {
            isLoggable = false;
        }
        return isLoggable;
    }
});
Iulian Ghionoiu
  • 366
  • 3
  • 5
  • Should be placed somewhere in the initialisation part of you application, before you start serving requests. – Iulian Ghionoiu Oct 16 '14 at 11:06
  • 5
    I think that you should try to solve the issue instead of hiding it. My 2 cents (I might be wrong also). – facundofarias Jan 29 '15 at 13:59
  • 1
    Why would that be safe to ignore!? Its clearly a problem as your code doesnt get it... If you are expecting to do something with the data, you clearly have a problem. Do not just ignore it.... @facundofarias is right. Burying you head in the sand and pretending you dont have a problem is stupid. – Nicholas Terry Apr 15 '16 at 22:02
  • It makes sense to ignore in a public API scenario where you can't control the funny things your API consumers might do when working on their integration, and you have too many of them to deal with the log noise. – kylejmcintyre Apr 06 '18 at 15:24
6

The following thread describes the warning you are receiving. It sounds as though you might have a filter defined in your web.xml that is processing the request before Jersey does.

Alex Winston
  • 651
  • 6
  • 10
6

Finally got rid of this by making sure I had Content-Type: application/json in my request headers (obviously, on the client side)

Arnold B.
  • 121
  • 1
  • 3
  • 1
    This would be a better answer if you could explain *why* we need this instead of `application/x-www-form-urlencoded`. – Stewart Jun 09 '17 at 10:11
4

I just had my ajax-function in JQuery set to contentType: "application/x-www-form-urlencoded; charset=UTF-8" because with a prior solution (without Jersey) I had some encoding problems. When I removed that the message was gone and everything worked fine.

cljk
  • 936
  • 1
  • 7
  • 20
2

Right. So I've been suffering this issue, and I've been trying to solve it on different ways, but I did't want to change my web.xml settings, just because if I was testing my application with Postman it worked perfect, but when it was being integrated with the webapp it fails with the mentioned issue (A servlet request to the URI {MY_URI} 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.)

So as @clijk mentioned, you only have to set your headers as:

"Content-Type":"application/json"
"charset":"UTF-8"

and voilá, the warning it's gone.

Thanks

facundofarias
  • 2,973
  • 28
  • 27
2

This warning is the only thing the WebComponent logs, so just turn logging up to ERROR level or turn off logging for this component in your logback.xml or wherever you have logging configured. You don't need to write a custom filter to ignore this specific message since there are no other messages logged from this component.

Source code snippet from org.glassfish.jersey.servlet.WebComponent version 2.14:

        if(!form.asMap().isEmpty()) {
            containerRequest.setProperty("jersey.config.server.representation.decoded.form", form);
            if(LOGGER.isLoggable(Level.WARNING)) {
                LOGGER.log(Level.WARNING, LocalizationMessages.FORM_PARAM_CONSUMED(containerRequest.getRequestUri()));
            }
        }

The localized message that is used for this warning message is:

form.param.consumed=A servlet request to the URI {0} 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.

Turn logging off for the WebComponent in your logback.xml like so:

<logger name="org.glassfish.jersey.servlet.WebComponent" level="OFF" additivity="false"/>
afenkner
  • 458
  • 1
  • 7
  • 10
0

In my case I've fixed this error when I've changed the Object Date to String in the method.

Error:

@POST
@Path("/myPath")
@Produces(MediaType.APPLICATION_JSON)
public List<MyObject> myMethod(@FormParam("StartDate") Date date) throws Exception {

Fixed

@POST
@Path("/myPath")
@Produces(MediaType.APPLICATION_JSON)
public List<MyObject> myMethod(@FormParam("StartDate") String date) throws Exception {
ferreirabraga
  • 87
  • 2
  • 5
0

Put this to your resource signature. Or find this string in your project someone already use this if @PUT or @POST is used. This should help

import javax.ws.rs.Consumes;

@Consumes(MediaType.APPLICATION_JSON)
Johnny Cage
  • 5,526
  • 2
  • 11
  • 7