Sawan
Sawan

Reputation: 160

Why @RequestParam annotation bind the value from request body?

I have this request

@RequestMapping(value = "/test", method = RequestMethod.POST)
public void test(ModelMap modelMap, @RequestParam(value = "name") String name) {
    modelMap.put("result",name);
}

When I call this request from Postman and pass the Name parameter in the request body and in the URL, the result is like this :

The result is from body

But if I remove the parameter from request body, the request is like this :

The result is from head

Why does @RequestParam annotation bind the value from the request body first? and if it doesn't exist in the body, it bind the value from URL parameters

Upvotes: 4

Views: 972

Answers (1)

JEY
JEY

Reputation: 7133

Because it's how ServletRequest works. Behind the scene @RequestParam is using ServletRequest#getParameter. If you take a look at the java doc it clearly state that query parameter or form post data are used.

For HTTP servlets, parameters are contained in the query string or posted form data.

If there is a multiple value for instance same key in query and post data then it returns the first value in the array returned by getParameterValues.

Furthermore you are using multipart/form-data content type so spring handle it with DefaultMultipartHttpServletRequest where parameters found in the body are returned first:

@Override
public String[] getParameterValues(String name) {
    String[] parameterValues = super.getParameterValues(name);
    String[] mpValues = getMultipartParameters().get(name);
    if (mpValues == null) {
        return parameterValues;
    }
    if (parameterValues == null || getQueryString() == null) {
        return mpValues;
    }
    else {
        String[] result = new String[mpValues.length + parameterValues.length];
        System.arraycopy(mpValues, 0, result, 0, mpValues.length);
        System.arraycopy(parameterValues, 0, result, mpValues.length, parameterValues.length);
        return result;
    }
}

Upvotes: 2

Related Questions