➤ How to Code a Game
➤ Array Programs in Java
➤ Java Inline Thread Creation
➤ Java Custom Exception
➤ Hibernate vs JDBC
➤ Object Relational Mapping
➤ Check Oracle DB Size
➤ Check Oracle DB Version
➤ Generation of Computers
➤ XML Pros & Cons
➤ Git Analytics & Its Uses
➤ Top Skills for Cloud Professional
➤ How to Hire Best Candidates
➤ Scrum Master Roles & Work
➤ CyberSecurity in Python
➤ Protect from Cyber-Attack
➤ Solve App Development Challenges
➤ Top Chrome Extensions for Twitch Users
➤ Mistakes That Can Ruin Your Test Metric Program
@RequestParam and @PathVariable in Spring Boot REST | We will discuss how to pass request parameters to the rest APIs. To pass request parameters @RequestParam and @PathVariable are used in Spring. First, let us see @RequestParam.
@RequestParam in Spring Boot REST
Request Parameter format: URL?key=val&key=val&key=val….
- Data is sent to the application using the URL in
key = val
format. - We can pass multiple key=val, it is not required to follow the order of parameters present in the method declaration.
- To Read Data:-
@RequestParam("key") DataType localVariable
// or
// keyName and variable name are same
@RequestParam DataType key
It even supports type conversion, (String -> int) based on the data type that you have provided. The default data type is String.
Many web apps are using RequestParam, even we can use same in webservices also.
https://www.google.com/search
? q=india
& oq=india
& aqs=chrome..69i57j46i275i433j0i131i433l3j0j69i60j69i65.2086j0j7
& sourceid=chrome
& ie=UTF-8
It internally uses the servlets concept.
@RequestParam("sid") Integer id
Servlets equivalent code:-
String sid = request.getParameter("sid");
Integer id = Integer.parseInt(sid);
Request Parameter Example:-
@RestController
public class ProductRestController {
@GetMapping("/data")
public String showData(@RequestParam Integer pid, @RequestParam String pcode,
@RequestParam Double pcost) {
return "{ pid :" + pid + ", pcode: " + pcode + ", pcost: " + pcost + " }";
}
}
URLs:-http://localhost:8080/data?pid=10&pcode=PEN&pcost=300
http://localhost:8080/data?pcode=PEN&pcost=400&pid=101
Here the order of parameters are not important.
@RequestParam(required = false, defaultValue = “value”)
How can we make RequestParam from required to optional param? By default, RequestParam is required (i.e. required = true
). In required = true
, case if we did not send data then FrontController returns 404-Not Found. But if we want to make it optional, then we have to mention a default value. RequestParam can be make optional having some default value as:- @RequestParam(required = false, default="value") DataType localVarible
. The default value must be passed as string.
@RestController
public class ProductRestController {
@GetMapping("/data")
public String showData(@RequestParam Integer pid, @RequestParam String pcode,
@RequestParam(required = false, defaultValue = "100") Double pcost) {
return "{ pid :" + pid + ", pcode: " + pcode + ", pcost: " + pcost + " }";
}
}
URL:- http://localhost:8080/data?pid=10&pcode=PEN
Response:- { pid :10, pcode: PEN, pcost: 100.0 }
@PathVariable in Spring Boot REST
There are two types of paths:-
- Static Path:- It indicates the location(Path) given to the resource(Controller#method). Example: /product/export, /employee/save .. etc.
- Dynamic Path:- It indicates sending data along with the URL as PathType without any key(Direct Value). Example: /product/{id} , /employee/find/{code} Here /{ } indicates dynamic path(i.e. send data at runtime).
@PathVariable is used for dynamic paths.
- PathVariables are also called clean URLs (No additional Symbols ? & as they are overloaded)
- It must follow the order. It avoids confusion for other devs/users.
- Execution is bit faster compared to @RequestParam.
- URL size also gets reduced.
With Request Param:- http://localhost:8080/data?pid=10&pcode=PEN&pcost=300
With Path Variable:- http://localhost:8080/data/10/PEN/300
To read data in the application, syntax is:-
@PathVariable("key") DataType localVariable
// or
// keyName and variable name are same
@PathVariable DataType key
It even supports type conversion, (String -> int) based on the data type that you have provided. The default data type is String.
While adding Path in code, we must specify static and dynamic path details using @___Mapping("___")
annotation.
3 Steps:-
- Define Dynamic Path at Method Level. Example:
@GetMapping("/employee/find/{eid}")
- Read Path Variable data at Method Param. Example:
@PathVariable Integer eid
- Pass data using Request URL. Example:
http://localhost:8080/employee/find/10
While making the request we must maintain the number of level counts in the code. It should be equal to URL Path levels. Example:-
In code: @GetMapping("/emp/find/data/{code}")
Request URLs:-
http://localhost:8080/emp/find/data/A | Valid |
http://localhost:8080/emp/find/data/A/B | 404 – Not Found |
http://localhost:8080/emp/find/data | 404 – Not Found |
If we compare the above cases with @RequestParam:-
http://localhost:8080/emp/find/data?code=A | Valid |
http://localhost:8080/emp/find/data?code=A&dec=B | Valid, Additional Param |
http://localhost:8080/emp/find/data | 400 – Bad Request |
Different Cases with @PathVariable in Spring Boot REST
Case#1:- Ambiguous handler methods
@GetMapping("/emp/find/{a}")
public String m1(@PathVariable String a) {
// code
}
@GetMapping("/emp/find/{b}")
public String m1(@PathVariable String b) {
// code
}
URL: http://localhost:8080/emp/find/ABC
Response: 500 – Internal Server Error. IllegalStateException: Ambiguous handler methods
Just because of name/datatype change in dynamic path, they are never going to be different URLs.
Case#2:- Multiple methods have the same request URL through static & dynamic path
If a Request URL is matched with multiple methods that are defined using PathVariables, then first priority is given to more static count levels. (static means letter to letter should be compared including case {case-sensitive} full path must be same). If not then come to the next level dynamic paths.
@RestController
public class ProductRestController {
@GetMapping("/emp/mode/code")
public String showA() {
return "FROM#A";
}
@GetMapping("/emp/mode/{code}")
public String showB(@PathVariable String code) {
return "FROM#B " + code;
}
@GetMapping("/emp/{mode}/{code}")
public String showC(@PathVariable String mode, @PathVariable String code) {
return "FROM#C " + mode + "," + code;
}
@GetMapping("/{emp}/{mode}/{code}")
public String showD(@PathVariable String emp, @PathVariable String mode,
@PathVariable String code) {
return "FROM#D " + emp + ", " + mode + "," + code;
}
}
If we call http://localhost:8080/emp/mode/code
then which method is matched? The showA()
method will be executed because the path ’emp/mode/code’ is matched.
We can even have paths with all dynamics(valid).
If we call http://localhost:8080/Emp/Mode/code
then which method is matched? URL is case-sensitive. The showA(), showB(), showC() methods start with '/emp'
but the URL contains '/Emp'
. The showD() method starts with the dynamic path therefore it will be executed.
URL | Selected Method |
/emp/mode/xyz | showB() |
/emp/xyz/xyz | showC() |
/emp/Mode/code | showC() |
/emp/Mode/xyz | showC() |
/xyz/xyz/xyz | showD() |
/Emp/xyz/xyz | showD() |
/Emp/Mode/xyz | showD() |
If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!