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.