Detailed explanation
In Spring MVC, @RequestParam, @PathVariable and @RequestBody bind different parts of an HTTP request to controller method arguments. @RequestParam reads request parameters, typically query-string values or URL-encoded form fields; @PathVariable extracts values captured by URI templates; @RequestBody reads and converts the request body. The REST convention is resource identity in the path, filtering and pagination in query parameters, and structured input in the body. For example, PUT /users/42?notify=true with a JSON payload can legitimately use all three annotations together.
@RequestParam("page") int page reads a parameter such as ?page=2. Parameters are required by default: a missing required value normally produces 400 Bad Request. Use required=false for optional parameters, choosing a nullable wrapper or Optional when appropriate. A defaultValue supplies a fallback for missing or empty values and implicitly makes the parameter optional. List<String> supports repeated values such as ?tag=java&tag=spring; an unnamed Map<String,String> collects parameters, while MultiValueMap preserves repeated values. Spring's conversion system converts strings into declared types; invalid numeric input normally produces 400.
@PathVariable("id") Long id reads 42 from a matching route such as /users/{id}. Route matching happens before argument binding: a URL that does not match any applicable mapping normally produces 404, whereas /users/abc matching this template produces 400 when conversion to Long fails. Path variables are required by default, but required=false can work with a nullable reference type; Optional is another option. Supporting an absent segment generally also requires a mapping without that segment. Explicit annotation names avoid dependence on compiler-retained parameter names.
@RequestBody delegates body conversion to an HttpMessageConverter selected using the target type and request Content-Type; Jackson commonly handles JSON when configured. It suits structured POST, PUT and PATCH payloads, including nested objects. With a validation provider configured, @Valid triggers Bean Validation; DTO violations normally raise MethodArgumentNotValidException and return 400. Malformed JSON normally returns 400, while unsupported media types return 415. Use one body argument because the request body is a single stream, and avoid GET bodies because they lack generally defined semantics. Interviewers look for correct source selection, conversion behaviour and error handling—not just annotation definitions.
Key points to remember
- @RequestParam binds query or form parameters and supports optional values, defaults and repeated parameters.
- @PathVariable binds URI-template values, commonly resource identifiers.
- @RequestBody converts the body into an object using an HttpMessageConverter.
- String parameter conversion and JSON deserialisation are different mechanisms; @Valid adds validation after binding.
- A controller method can combine all three, for example an update with an ID, a notification flag and a JSON DTO.
Common mistakes candidates make
- Claiming @RequestParam reads only query strings, or that it extracts fields from a JSON body.
- Saying every path-variable problem returns 404: a matched route with an invalid numeric ID normally returns 400.
- Assuming @RequestBody automatically validates constraints or that required=false requires an Optional path-variable argument.
Likely follow-up questions
How is @ModelAttribute different from @RequestBody?
@ModelAttribute creates or obtains an object and binds request parameters onto its properties, commonly for forms. @RequestBody instead uses an HttpMessageConverter to deserialize the body, commonly JSON.
How do you handle optional inputs safely?
For @RequestParam, use a defaultValue, Optional<T>, or required=false with a nullable reference type. An optional path variable also needs a route that matches without the segment; required=false alone does not change route matching.
Should parameter names be explicitly included in annotations?
Using @RequestParam("page") and @PathVariable("id") avoids reliance on Java parameter-name discovery. If you omit these names, compile with -parameters, particularly with modern Spring versions.
Interview tip: Start with “query or form, URI template, and body”, then demonstrate all three using one update request and explain the main error cases.
