This post will give brief idea about creating views, controller in Spring.
Note: The code can be downloaded. URL for download is present at the end.
A simple example : Store the information of a person. The property of a person is Name and City with a unique id.
The model class will be
public class PersonForm { private String name; private String city; private int id = -1; public PersonForm(int id,String name, String city ) { this.name = name; this.city = city; this.id = id; } public PersonForm() { // TODO Auto-generated constructor stub } // include getters and setters }
Following functionalities can be defined:
- Create a user
- Edit a user
- Delete a user
- Show all users
The url mappings can be defined
URL | Function | jsp page |
---|---|---|
/person , Request Type = GET | Show all users | show.jsp |
/person , Request Type = POST | Save a user | user.jsp |
/person/newuser , Request Type = GET/td> | Show a blank form to enter user details | user.jsp |
/person/delete/{id} , Request Type = POST | Delete a user | show.jsp |
/person/update/{id} , Request Type = POST | Update a user | user.jsp |
Note: The user is stored simply using a HashMap ( for simplicity) . Ideally all calls should go to DB.
Lets create the Controller where all the actions happen.
@RequestMapping("/person") @Controller /** Displaying CRUD functionality. **/ public class PersonController { Map<Integer, PersonForm> personList = new HashMap<Integer, PersonForm>(); static int id = 0; /** * Save a user and return back to display all users */ @RequestMapping(method=RequestMethod.POST) public ModelAndView save(PersonForm form,BindingResult errors, HttpServletRequest request, HttpServletResponse response){ if(form.getId() == -1){ id++; form.setId(id); personList.put(id,form); }else{ personList.put(form.getId(), form); }; ModelMap map = new ModelMap(); Iterator iter = personList.keySet().iterator(); List<PersonForm> newMap = new ArrayList<PersonForm>(); while(iter.hasNext()){ Object key = iter.next(); if(key != null) newMap.add(personList.get(key)); } map.put("persons",newMap); return new ModelAndView("show",map); } @RequestMapping(value="/newuser",method=RequestMethod.GET) public ModelAndView newUser(){ PersonForm form = new PersonForm(); ModelMap map = new ModelMap(); map.put("person", form); return new ModelAndView("user",map); } /** * * Display all users */ @RequestMapping(method=RequestMethod.GET) public String displayAll( HttpServletRequest request){ ModelMap map = new ModelMap(); Iterator iter = personList.keySet().iterator(); List<PersonForm> newMap = new ArrayList<PersonForm>(); while(iter.hasNext()){ Object key = iter.next(); if(key != null) newMap.add(personList.get(key)); } map.put("persons",newMap); request.setAttribute("persons", newMap); return "show"; } /** Delete a user and return back to all list **/ @RequestMapping(value="/delete/{id}") public String delete(@PathVariable String id, HttpServletRequest request){ personList.remove(Integer.parseInt(id)); Iterator iter = personList.keySet().iterator(); List<PersonForm> newMap = new ArrayList<PersonForm>(); while(iter.hasNext()){ Object key = iter.next(); if(key != null) newMap.add(personList.get(key)); } request.setAttribute("persons", newMap); return "show"; } /** Update a user and return back to all list **/ @RequestMapping(value="/update/{id}") public ModelAndView update(@PathVariable String id){ ModelMap map = new ModelMap(); map.put("person", personList.get(Integer.parseInt(id))); return new ModelAndView("user",map); } }
Here all the actions happen:
- @Controller: is used to tell Spring that PersonController is a controller
- @RequestMapping(class-level): Annotation for mapping web requests onto specific handler classes and/or handler methods.All urls inside this controller should precede with the url mentioned as the value.
- @RequestMapping(method-level): The function will be called if the url maps the given value. Other attributes can be set as RequestType(GET or POST etc) .
- ModelAndView: This class merely holds both(Model and view) to make it possible for a controller to return both model and view in a single return value. The object tell which view to resolve and what model object should be passed.
- ModelMap: Implementation of Map(LinkedHashMap),building model data for use with UI tools.Basically replacement of setting values as request attribute.
- Method such as delete and displayAll returns the String. The return value is mapped to view name. The view name is resolved using InternalResourceViewResolver configured in mvc-dispatcher-servlet.xml.
- The update or delete url are mapped as /update/{id}.. Any parameter defined in {} can be accessed using @PathVariable
- Note: I have defined controller to view mapping in couple of ways. There are more ways to define.
Now its the turn of views:
user.jsp
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <form:form commandName="person" method="post" action="/SpringMVC/person"> <form:hidden path="id" id="id" /> <table> <tr> <td><label>Name</label></td> <td><form:input path="name" id="name"/></td> </tr> <tr> <td><label>City</label></td> <td><form:input path="city" id="city"/></td> </tr> <tr> <td><input type="submit" name="save" value="save"/></td> </tr> </table> </form:form> </body> </html>
This view is used to save and update the users.
index.jsp
<%@ page language="java" errorPage="/error.jsp" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <body> <h1>List Of People</h1> <table> <tr> <th>Name</th> <th>City</th> </tr> <c:forEach items="${persons}" var="person"> <tr> <td>${person.name}</td> <td>${person.city}</td> <td> <a href="/SpringMVC/person/delete/${person.id}">DELETE</a> </td> <td> <a href="/SpringMVC/person/update/${person.id}">EDIT</a> </td> </tr> </c:forEach> </table> </body> </html>
Now the configuration:
The web.xml is pretty basic .. Declaring the org.springframework.web.servlet.DispatcherServlet and loading the spring servlet.xml. The code can be downloaded at the end.
mvn-dispatcher-servlet.xml is very basic for this example
<context:component-scan base-package="com.common.controller" /> <context:annotation-config /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/pages/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean>
This <context:annotation-config /> tells that spring in annotation enabled.
This <context:component-scan base-package> tells where beans are configured.
And InternalResourceViewResolver resolve view names to jsp pages present in WEB-INF/pages.