@RequestParam vs @PathVariable
Asked Answered
S

9

417

What is the difference between @RequestParam and @PathVariable while handling special characters?

+ was accepted by @RequestParam as space.

In the case of @PathVariable, + was accepted as +.

Sandrasandro answered 5/12, 2012 at 3:25 Comment(0)
H
563

If the URL http://localhost:8080/MyApp/user/1234/invoices?date=12-05-2013 gets the invoices for user 1234 on December 5th, 2013, the controller method would look like:

@RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
public List<Invoice> listUsersInvoices(
            @PathVariable("userId") int user,
            @RequestParam(value = "date", required = false) Date dateOrNull) {
  ...
}

Also, request parameters can be optional, and as of Spring 4.3.3 path variables can be optional as well. Beware though, this might change the URL path hierarchy and introduce request mapping conflicts. For example, would /user/invoices provide the invoices for user null or details about a user with ID "invoices"?

Hesychast answered 5/12, 2012 at 7:47 Comment(14)
@PathVariable can be used in any RequestMethodToxicology
When using Java 8, the PathVariable's name is inferred to be the argument name, so the above can be written as: @PathVariable int userIdAmmunition
@AlexO: this has nothing to do with java8, it works even for java 5 and Spring3.0: The point is that the code is compiled with debugging enabled.Hesychast
A null value for @PathVariable will be shown as /user//invoices and not /user/invoices. I think they'll be treated differently. Maybe /user{userId}/invoices will have problems, I don't know.Artiodactyl
@Hesychast Correct, this works with debugging before Java 8. Since Java 8 it also works without debugging, instead using "-parameters": docs.spring.io/spring/docs/current/spring-framework-reference/… docs.oracle.com/javase/tutorial/reflect/member/…Ammunition
@Hesychast Can @PathParam and @RequestParam be declared without using @RequestMapping?Barham
@user3705478: i do not think so, because spring need to know that this is an request handler method. (and of course: @PathParam works only if there is a placeholder in the uri template)Hesychast
@Hesychast I think we both meant @PathVariable , but since I started with @PathParam you also referred the same. Correct?Barham
@user3705478: Sorry, of course, it is noit @PathParam but @PathVariableHesychast
@ralph when I did a Google search I do see @PathParam , but I actually don't get it.Barham
@user3705478: @PathParam is an javax.ws.rs annotation. docs.oracle.com/javaee/7/api/javax/ws/rs/PathParam.htmlHesychast
If they had just called @RequestParam instead @QueryVariable (or @QueryParam), it'd be much more obvious when to use it vs. @PathVariable.Saltine
very straight forward and simple explanation. I rather not to use the backslash enable in catalina properties. It seems not working.Thanks!!Spellman
I have a question regarding this. Is it possible to pass a defined POJO object to the @RequestParam and still gets the same result as each @RequestParam you define in the controller?Octad
F
132

@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&param2=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:

  • defaultValue – This is the default value as a fallback mechanism if request is not having the value or it is empty.
  • name – Name of the parameter to bind
  • required – Whether the parameter is mandatory or not. If it is true, failing to send that parameter will fail.
  • value – This is an alias for the name attribute

@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&param2=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" >
Fiddlehead answered 14/10, 2016 at 10:0 Comment(3)
Will a string, such as userName have a type param or not? I'm leaning towards making it a variable, but it could be a param too.Artiodactyl
..And here is the original post :- javabeat.net/spring-mvc-requestparam-pathvariablePatriciate
Can @PathParam and @RequestParam be declared without using @RequestMappingBarham
E
37

@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;
}
Elsewhere answered 6/9, 2018 at 2:18 Comment(0)
T
37
  1. @RequestParam is used to extract query parameters from URL:

    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 for mapping dynamic values from the URL to a method parameter:

    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 could also be used in Spring MVC to bind form parameter names to method parameters in a controller. Here's an example of a simple Spring MVC controller that accepts form data submitted using the POST method.

<form action="/submit-form" method="post">
  <label for="name">Name:</label>
  <input type="text" id="name" name="name"><br><br>
  
  <label for="email">Email:</label>
  <input type="email" id="email" name="email"><br><br>
  
  <input type="submit" value="Submit">
</form>
   @Controller
   public class FormController {

       @PostMapping("/submit-form")
       public String handleSubmitForm(
          @RequestParam(name = "name") String name,
          @RequestParam(name = "email") String email) {
             ....
             ....
             // return a view based on processing
             return "formSuccess";
       }
   }
  1. By default, a @PathVariable is always considered required. If a corresponding path segment is missing, Spring will result in a 404 Not Found error. @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";
     }    
    
Tiedeman answered 28/11, 2019 at 11:59 Comment(3)
Is your argument 2 opinion based or can you provide any resource which supports that thesis?Phenylketonuria
@AnnaKlein. Here is docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/…Tiedeman
flawless answer @TiedemanNoisy
M
1

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

Magdeburg answered 26/9, 2014 at 2:13 Comment(0)
P
1
@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) {

}
Penguin answered 20/12, 2016 at 17:14 Comment(0)
L
1

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:

  1. localhost:7000/pvar/!@#$%^&*()_+-=[]{}|;':",./<>?
  2. localhost:7000/rpvar?param=!@#$%^&*()_+-=[]{}|;':",./<>?

!@ was received as response in both the requests

Ligature answered 27/12, 2019 at 15:18 Comment(0)
K
0

@RequestParam:We can say it is query param like a key value pair @PathVariable:-It is came from URI

Kelter answered 27/11, 2021 at 12:4 Comment(1)
Format code snippets to improve readabilityFerdy
P
0

As per my understanding

Case 1 (@RequestParam) : Assume if url like key value pairs

http://localhost:8080/getStudent?aid=101

Here we will use @RequestParam annotation for getting values.

Example :

 @RequestMapping("/getStudent") 
 @ResponseBody 
 public String getStudentById(@RequestParam("aid") int aid) {
     String res=repo.findById(aid).toString();
     return res; 
 }

Case 2 (@PathVariable): Assume if url like

http://localhost:8080/getStudent/101

Here we will use @PathVariable annotation for getting values.

Example:

 @RequestMapping("/getStudent/{aid}") 
 @ResponseBody 
 public String getStudentById(@PathVariable("aid") int aid) {
     String res=repo.findById(aid).toString();
     return res; 
 }
Pavyer answered 5/11, 2023 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.