I use spring-boot 2.2.x

My code is:

   @PostMapping(path = "/testFormData", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
  public BaseResult testFormData(@RequestParam(name = "name") String name,
      @RequestParam(name = "age") Integer age) {
    log.info("api testFormData name is {}, age is {}", name, age);
    return BaseResult.success(name + "---" + age);
  }

and I use curl:

 curl -XPOST "http://127.0.0.1:8082/api/testFormData"  -d "name=jackson&age=24"

and it throws a MissingServletRequestParameterException.

If I use spring-boot 2.1.x, the request is OK.

How can I resolve application/x-www-form-urlencoded post request?

Comment From: sbrannen

Does it make a difference if you explicitly specify the content type?

curl -d "name=jackson&age=24" -H "Content-Type: application/x-www-form-urlencoded" -X POST http://127.0.0.1:8082/api/testFormData

Comment From: mdeinum

Isn't this the cUrl behavior when using " instead of '? With a double quote it will encode the string as is, with a single one it will do some processing to determine multiple parameters?

so

curl -XPOST "http://127.0.0.1:8082/api/testFormData"  -d "name=jackson&age=24"

will result in a parameter name with value jackson%26age%3D24.

Where as

curl -XPOST "http://127.0.0.1:8082/api/testFormData"  -d 'name=jackson&age=24'

will lead to 2 parameters name and age with the respective values.

Comment From: sbrannen

Using the free Postman Echo service on my Mac...

curl -X POST -d "foo1=bar1&foo2=bar2" https://postman-echo.com/post

--> "form":{"foo1":"bar1","foo2":"bar2"}

Whereas,

curl -X POST --data-urlencode "foo1=bar1&foo2=bar2" https://postman-echo.com/post

--> "form":{"foo1":"bar1&foo2=bar2"}

Note the difference between -d and --data-urlencode.

@dragontree101, what operating system (and terminal/shell) are you executing that curl command from?

Comment From: dragontree101

@sbrannen i use mac pro, i both use use curl and postman have the same problem

Comment From: sbrannen

@dragontree101, what happens if you execute the following?

curl -X POST http://127.0.0.1:8082/api/testFormData -d 'name=jackson' -d 'age=24'

Comment From: dragontree101

i create new project from https://start.spring.io/ and not this problem, maybe i add some other dependency cause this problem. i will debug this problem in my computer.

Comment From: sbrannen

i will debug this problem in my computer.

OK. Thanks

Comment From: dragontree101

i found i add an accessLogFilter, and create a HttpServletRequestAdapter

if i add

requestWrapper = new HttpServletRequestAdapter(request, bytes);

param has this problem

if i am not use

HttpServletRequestAdapter

every thing is ok

 @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
      FilterChain filterChain) throws ServletException, IOException {
    HttpServletRequestAdapter requestWrapper = null;
    ContentCachingResponseWrapper responseWrapper = null;
    byte[] bytes = IOUtils.toByteArray(request.getInputStream());

    requestWrapper = new HttpServletRequestAdapter(request, bytes);
    filterChain.doFilter(request, response);
  }

public class HttpServletRequestAdapter extends HttpServletRequestWrapper {

    private InputStream inputStream;

    public HttpServletRequestAdapter(HttpServletRequest request, byte[] payload) {
      super(request);
      inputStream = new ByteArrayInputStream(payload);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
      return new ServletInputStream() {
        @Override
        public boolean isFinished() {
          return false;
        }

        @Override
        public boolean isReady() {
          return false;
        }

        @Override
        public void setReadListener(ReadListener listener) {

        }

        @Override
        public int read() throws IOException {
          return inputStream.read();
        }
      };
    }
  }

but i use spring-boot 2.1.x also add this accessLogFilter, request param is ok.

Comment From: mpreziuso

We were having the same problem and we later realised it was because of a filter in the chain that was consuming the request InputStream.

If you are doing the same, ContentCachingRequestWrapper and ContentCachingResponseWrapper may be useful as well as relying on AbstractRequestLoggingFilter if you're doing that for logging purposes.