What is the difference between @RequestParam
and @PathVariable
while handling special characters?
+
was accepted by @Re
1) @RequestParam
is used to extract query parameters
http://localhost:3000/api/group/test?id=4
@GetMapping("/group/test")
public ResponseEntity<?> test(@RequestParam Long id) {
System.out.println("This is test");
return ResponseEntity.ok().body(id);
}
while @PathVariable
is used to extract data right from the URI:
http://localhost:3000/api/group/test/4
@GetMapping("/group/test/{id}")
public ResponseEntity<?> test(@PathVariable Long id) {
System.out.println("This is test");
return ResponseEntity.ok().body(id);
}
2) @RequestParam
is more useful on a traditional web application where data is mostly passed in the query parameters while @PathVariable
is more suitable for RESTful web services where URL contains values.
3) @RequestParam
annotation can specify default values if a query parameter is not present or empty by using a defaultValue
attribute, provided the required attribute is false
:
@RestController
@RequestMapping("/home")
public class IndexController {
@RequestMapping(value = "/name")
String getName(@RequestParam(value = "person", defaultValue = "John") String personName) {
return "Required element of request param";
}
}
it may be that the application/x-www-form-urlencoded midia type convert space to +, and the reciever will decode the data by converting the + to space.check the url for more info.http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
@RequestParam is use for query parameter(static values) like: http://localhost:8080/calculation/pow?base=2&ext=4
@PathVariable is use for dynamic values like : http://localhost:8080/calculation/sqrt/8
@RequestMapping(value="/pow", method=RequestMethod.GET)
public int pow(@RequestParam(value="base") int base1, @RequestParam(value="ext") int ext1){
int pow = (int) Math.pow(base1, ext1);
return pow;
}
@RequestMapping("/sqrt/{num}")
public double sqrt(@PathVariable(value="num") int num1){
double sqrtnum=Math.sqrt(num1);
return sqrtnum;
}
@PathVariable - must be placed in the endpoint uri and access the query parameter value from the request
@RequestParam - must be passed as method parameter (optional based on the required property)
http://localhost:8080/employee/call/7865467
@RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
public List<Calls> getAgentCallById(
@PathVariable(“callId") int callId,
@RequestParam(value = “status", required = false) String callStatus) {
}
http://localhost:8080/app/call/7865467?status=Cancelled
@RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
public List<Calls> getAgentCallById(
@PathVariable(“callId") int callId,
@RequestParam(value = “status", required = true) String callStatus) {
}
Both the annotations behave exactly in same manner.
Only 2 special characters '!' and '@' are accepted by the annotations @PathVariable and @RequestParam.
To check and confirm the behavior I have created a spring boot application that contains only 1 controller.
@RestController
public class Controller
{
@GetMapping("/pvar/{pdata}")
public @ResponseBody String testPathVariable(@PathVariable(name="pdata") String pathdata)
{
return pathdata;
}
@GetMapping("/rpvar")
public @ResponseBody String testRequestParam(@RequestParam("param") String paramdata)
{
return paramdata;
}
}
Hitting following Requests I got the same response:
!@ was received as response in both the requests
@RequestParam annotation used for accessing the query parameter values from the request. Look at the following request URL:
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
In the above URL request, the values for param1 and param2 can be accessed as below:
public String getDetails(
@RequestParam(value="param1", required=true) String param1,
@RequestParam(value="param2", required=false) String param2){
...
}
The following are the list of parameters supported by the @RequestParam annotation:
@PathVariable
@PathVariable identifies the pattern that is used in the URI for the incoming request. Let’s look at the below request URL:
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
The above URL request can be written in your Spring MVC as below:
@RequestMapping("/hello/{id}") public String getDetails(@PathVariable(value="id") String id,
@RequestParam(value="param1", required=true) String param1,
@RequestParam(value="param2", required=false) String param2){
.......
}
The @PathVariable annotation has only one attribute value for binding the request URI template. It is allowed to use the multiple @PathVariable annotation in the single method. But, ensure that no more than one method has the same pattern.
Also there is one more interesting annotation: @MatrixVariable
http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,+10.40,+3.91;AZN=236.00,+103.00,+3.29;SBRY=375.50,+7.60,+2.07
And the Controller method for it
@RequestMapping(value = "/{stocks}", method = RequestMethod.GET)
public String showPortfolioValues(@MatrixVariable Map<String, List<String>> matrixVars, Model model) {
logger.info("Storing {} Values which are: {}", new Object[] { matrixVars.size(), matrixVars });
List<List<String>> outlist = map2List(matrixVars);
model.addAttribute("stocks", outlist);
return "stocks";
}
But you must enable:
<mvc:annotation-driven enableMatrixVariables="true" >