Mapping data using @ModelAttribute

In this section, we will implement the feature to insert a new course. In the process, we will learn more about mapping requests to methods and mapping request parameters to method arguments.

In the previous section, we implemented CourseController with one method, getCourses. We will now add methods to insert new courses. To add a course, we first need to display a View with a form that accepts the user input. When the user actually submits the form, the form data should be posted to a URL that handles insertion of the data to the database. Therefore, there are two requests involved here: the first is to display the add course form, and the second is to handle the data posted from the form. We will call the first request addCourse and the second request doAddCourse. Let's first create the user interface. Create a new JSP and name it addCourse.jsp. Add the following markup to the body of the page (JSTL and other header declarations are skipped to save space):

  <h2>Add Course</h2> 
  <c:if test="${not empty error}"> 
    <span style="color:red;"> 
      ${error}<br> 
    </span> 
  </c:if> 
 
  <c:set var="actionPath" 
value="${pageContext.request.contextPath}/doAddCourse"/> <form method="post" action="${actionPath}"> <table> <tr> <td>Course Name:</td> <td><input type="text" name="name" value="${course.name}">
</td> </tr> <tr> <td>Credits:</td> <td><input type="text" name="credits"
value="${course.credits}"> </td> </tr> <tr> <td colspan="2"> <button type="submit">Submit</button> </td> </tr> </table> <input type="hidden" name="id" value="${course.id}"> </form>

The page expects a course variable to be made available by the controller. In the form body, it assigns the values of the course to appropriate input fields; for example, the ${course.name} value is assigned to the text input for Course Name. The form posts the data to the "${pageContext.request.contextPath}/doAddCourse" URL. Note that since our application is not deployed in the root context, we need to include the context name in the URL.

Let's now add Controller methods to handle two requests for add: addCourse and doAddCourse. When the addCourse request is made, we want to serve the page that displays the input form. When the user clicks the Submit button, we want form data to be sent using the doAddCourse request. Open the CourseController class and add the following method:

  @RequestMapping("/addCourse") 
  public String addCourse (@ModelAttribute("course") CourseDTO 
course, Model model) { if (course == null) course = new CourseDTO(); model.addAttribute("course", course); return "addCourse"; }

The addCourse method is configured, using the @RequestMapping annotation, to handle  request URLs starting (relative to context root) with "/addCourse". If previously the  course attribute was added to Model, then we want this object to be passed as an argument to this function. Using @ModelAttribute, we tell the Spring Framework to inject the Model attribute called course if it is present and assign it to the argument named course; else, null is passed. In the case of the first request, Model would not have a course attribute, so it would be null. In the subsequent requests, for example, when the user-entered data in the form (to add a course) is not valid and we want to redisplay the page, Model will have the course attribute.

We will now create a handler method for the '/doAddCourse' request. This is a POST request sent when the user submits the form in addCourse.jsp (refer to the form and its POST attribute discussed earlier):

  @RequestMapping("/doAddCourse")  
  public String doAddCourse (@ModelAttribute("course") CourseDTO 
course, Model model) { try { coursesDAO.addCourse(course); } catch (Throwable th) { model.addAttribute("error", th.getLocalizedMessage()); return "addCourse"; } return "redirect:courses"; }

The doAddCourse method also asks Spring to inject the Model attribute called course as the first argument. It then adds the course to the database using CourseDAO. In the case of an error, it returns the addCourse string, and Spring MVC displays addCourse.jsp again. If the course is successfully added, then the request is redirected to courses, which tells Spring to process and display courses.jsp. Recall that in servlet-context.xml (the Spring context configuration file in the src/main/webapp/WEB-INF/spring/appServlet folder), we configured a bean with the org.springframework.web.servlet.view.InternalResourceViewResolver class. This class is extended from UrlBasedViewResolver, which understands how to handle URLs with redirect and forward prefixes. So, in doAddCourse we save the data in the database, and if successful, we redirect the request to courses, which displays (after processing courses.jsp) the list of courses.

At this point, if you want to test the application, browse to http://localhost:8080/course_management/addCourse. Enter the course name and credits and click Submit. This should take you to the courses page and display the list of courses.

Note that Spring MVC looks at the form field names and properties of the object in Model (in this case, CourseDTO) when mapping form values to the object. For example, the form field name is mapped to the CourseDTO.name property. So, make sure that the names of the form fields and the property names in the class (objects of which are added to the Model) are the same.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.236.70