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.