For our example, we’ll use a module called ‘Employee’. For this example, we’ll need to display an employee’s personal details, in addition to other information, on the main employeeDetail page. We’ll separate the main page into several small jsp pages. The file that will display the employee’s personal information is empPersonalDetails.jsp and that page must be included in the main page (employeeDetails.jsp), using action.
Let’s assume that you have used apache tiles to provide consistent layout for each such sub-page (due to some requirement or just for decorative purpose) and you want to include that through a controller call. To accomplish that, you will use code similar to what we have detailed below:
@Controller
@RequestMapping("/employee")
public class EmployeeController{
@RequestMapping (value = “/empPersonalDetails”)
public ModelAndView showEmpPersonalDetails(ModelMap modelMap){
//code to fetch employee personal details from database
//set model values
return new ModelAndView(“empPersonalDetails”);
}
}
employeeDetails.jsp
<jsp:include page=”/employee/empPersonalDetails.html”></jsp:include>
Note: empPersonalDetails.html in above action, will result in a call to the controller method which will return an appropriate tile-view (empPersonalDetails) along with the required model values.
The requirement is achieved here, but, as you may have noticed, the URL to refer to the Employee module is statically specified in , i.e. “/employee/…”
One drawback of this is that, in the future, if you need to change the URL of the module, i.e., the value of @RequestMapping for the controller class, or add another level in the URL, you will need to reflect those changes in all such places where you have statically specified the URL.
There is a way to obtain the controller-level request-mapping URL dynamically, using a Class.getAnnotation() API. The following code will return the URL specified as the value in @RequestMapping annotation of EmployeeController class.
String empModuleURL = EmployeeController.class.getAnnotation(RequestMapping.class).value()[0].toString());
In , you’ll want to use the URL value returned by the above code. The straightforward way to make the value available in the jsp file is to set the model attribute using ModelMap in the EmployeeController class, in the method responsible to return the view for main EmployeeDetail page. But, to achieve a better design and to accommodate other modules and URLs, you may wish to set the model attribute commonly for all controllers.
In Spring, this can be done using a Controller Advice class which will act as a global handler for the application. In the following example, we will use the @ControllerAdvice annotation to mark the GlobalHandler.java as a controller advice class.
@ControllerAdvice
public class GlobalHandler {
@ModelAttribute(“moduleURLs”)
public HashMap<String, String> getModuleURL(){
HashMap<String, String> moduleURLMap=new HashMap<String, String>();
moduleURLMap.put(“employeeModule”,EmployeeController.class.getAnnotation(RequestMapping.class).value()[0].toString());
.
.
//Add URLs for other modules
return moduleURLMap;
}
}
Note the use of @ModelAttribute annotation for marking the getModuleURL() method as a form-backing method to make the required model values available in the view.
Now, the URL for the ’employee’ module will be available as the value of “employeeModule” attribute in the EmployeeDetails.jsp file.
The following code will replace the previously mentioned code line in the EmployeeDetails.jsp file. Note how EL is used to access the URL value.
Using this technique will ensure that the code will make a call using whatever module URL has been specified for the controller class. By using the techniques defined and described in this article, the developer will assure that his or her code remains relevant and is not broken by future changes.