Sunday, February 26, 2023

Spring MVC @PathVariable Example - Creating Dynamic URL

In this Spring web MVC example we’ll see how request data can be passed to the controller using @PathVariable annotation along with @RequestMapping annotation.


Spring @RequestMapping with @PathVariable annotation

If you are passing parameters as the part of the request path, for example spring-mvc/getUser/101 then you can use @PathVariable annotation to retrieve the parameter from the request path. @RequestMapping annotation will have a placeholder to match the parameter with in the URL. That way you can pass dynamic URLs in your Spring MVC application where the place holder part of the URL can vary.

Spring web MVC example with @PathVariable annotation

In this Spring MVC example we’ll have a JSP (home page) from where the entered userId is sent in the request path.

home.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring MVC tutorial - Home JSP</title>

</head>

<body>
<script type="text/javascript">
function OnSubmitForm()
{
   var userid = document.getElementById("userid").value;
   document.userform.action="getUser/"+userid;
   return true;
}
</script>
    <h1>Hello World!</h1>
    <h4>Message- </h4><span>${message}</span>
    <form name="userform" method="post" onsubmit="return OnSubmitForm();">         
          User ID: <input type="text" id="userid" name="userid">                        
         <input type="submit" value="Submit">
    </form>
</body>
</html>

In the JSP, at the time of submitting the form userId is added to the action, using the Java script function, so that the URL has the userID too.

Spring MVC @PathVariable example - Controller class

The controller method with the appropriate @RequestMapping with a placeholder for userId will handle this request. With in the controller method there is also a @PathVariable annotation with a parameter. The value matching the placeholder is assigned to this parameter.

@Controller
public class MessageController {
 @RequestMapping(value = "/", method = RequestMethod.GET)
 public String showHome(Model model) {
  //model.addAttribute(new User());
  model.addAttribute("message", "MVC Example with dynamic URL");
  return "home";
 }
 
 @RequestMapping(value = "/getUser/{userId}", method = RequestMethod.GET)
 public String getUser(@PathVariable("userId") String userId, Model model) {
  // adding the user object to model
  // ideally get it from DB
  model.addAttribute("USER", findUserById(userId));
  return "user";
 }
 
 // Dummy Method-- Creating user object
 private User findUserById(String userId) {
  System.out.println("User ID " + userId);
  User user = new User();
  user.setUserId(userId);
  user.setFirstName("Leonard");
  user.setLastName("Nimoy");
  return user;
 }
}

As you can see in the Controller class there is a method getUser() with @RequestMapping annotation having the value as "/getUser/{userId}". Here {userId} part is the placeholder. Also there is a @PathVariable annotation with the matching value as the placeholder - @PathVariable("userId") and a parameter userId. A URL in the following form /getUser/101 will be matched to the @RequestMapping, Spring framework looks for the @PathVariable having the same value parameter as the placeholder. If found the parameter annotated with the @PathVariable annotation is assigned the value in placeholder.

Note that if method parameter name is same as the placeholder name in the @RequestMapping then the value parameter on @PathVariable is optional. So the same method can also be written as-

@RequestMapping(value = "/getUser/{userId}", method = RequestMethod.GET)
public String getUser(@PathVariable String userId, Model model) {
 
}

Once you have the userId, you can fetch user details using that ID from DB. Here we have dummy method to create a User object. That user object is then set into the Model. The returned logical view name is “user” that resolves to another JSP called user.jsp where the bound user object fields are displayed.

User.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring MVC tutorial - User</title>
</head>
<body>
<div>First Name: ${USER.firstName}</div>
<div>Last Name: ${USER.lastName}</div>
</body>
</html> 

Model Bean – Spring MVC @PathVariable example

The model bean used here is as follows.

public class User {
 private String firstName;
 private String lastName;
 private String userId;
 public String getUserId() {
  return userId;
 }
 public void setUserId(String userId) {
  this.userId = userId;
 }
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
}

Home page

Spring MVC @PathVariable example

User page

Spring MVC @PathVariable example

Having more than one @PathVariable annotations

You can have more than one placeholders matching more than one parameters in the request path and more than one @PathVariable annotations with method parameters corresponding to those placeholders. For example-

@RequestMapping(value = "/getUser/{firstName}/{lastName}", method = RequestMethod.GET)
public String getUserByName(@PathVariable String firstName, @PathVariable String lastName, Model model) {
 ...
 ...
}

@RequestMapping with regular expression

If you want to put some constraint on the placeholder matching with in the @RequestMapping annotation you can use regular expressions to define the placeholder. For example- If you want to ensure that userId has to be 4 digits.

@RequestMapping(value = "/getUser/{userId:\\d{4}}", method = RequestMethod.GET)
public String getUser(@PathVariable("userId") String userId, Model model) {

}

That's all for this topic Spring MVC @PathVariable Example - Creating Dynamic URL. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Web MVC Tutorial
  2. Spring Web MVC Java Configuration Example
  3. Spring MVC Dot (.) Truncation Problem With @PathVariable Annotation
  4. Spring MVC PDF Generation Example
  5. Transaction Management in Spring

You may also like-

  1. Spring Transaction Attributes - Propagation And Isolation Level Settings
  2. Spring Batch Processing Using JDBCTemplate batchUpdate() Method
  3. registerShutdownHook() Method in Spring Framework
  4. Circular Dependency in Spring Framework
  5. Difference Between Encapsulation And Abstraction in Java
  6. Java Collections Interview Questions And Answers
  7. How to Remove Duplicate Elements From an ArrayList in Java
  8. Java Object Cloning - clone() Method

2 comments:

  1. Hi,
    In above case where i get values from path variable, the base path of all the resources on the following page changes and then unable to fetch images and other resources on that jsp.
    eg. /myProject/resources/images/logo1.png is the base path for resources but I am getting /slt_automation_testing/projectDashboard/resources/images/logo1.png as path for my image

    controller method
    @RequestMapping(value="/projectDashboard/{projectId}")
    public ModelAndView projectDashboard(@PathVariable("projectId") String projectId, ModelMap model, HttpSession session)

    ReplyDelete
    Replies
    1. Difficult to point out the cause with this info .. can point out at usual suspects like having request mapping at the controller class level also which is getting added.

      Delete