5.9. Adding a CarTo add a new car, we'll create a new link on the viewCarList page, as in Figure 5-2. Figure 5-2. viewCarList with Add Car linkThis link will submit an addCar action request to our ControllerServlet (http://localhost:8080/jaw/controller?action=addCar). The ControllerServlet in Example 5-16 places an empty CarDTO in the Request scope and redirects to the carForm.jsp page. Example 5-16. ControllerServlet.java// perform action if(VIEW_CAR_LIST_ACTION.equals(actionName)) { CarDAO carDAO = new HibernateCarDAO( ); request.setAttribute("carList", carDAO.findAll( )); destinationPage = "/carList.jsp"; } else if(ADD_CAR_ACTION.equals(actionName)) { request.setAttribute("car", new CarDTO( )); destinationPage = "/carForm.jsp"; } else { String errorMessage = "[" + actionName + "] is not a valid action."; request.setAttribute(ERROR_KEY, errorMessage); } The carForm.jsp page in Figure 5-3 allows the user to type in the details of a new car and save it. Figure 5-3. carForm.jspExample 5-17 shows the JSP code. Example 5-17. carForm.jsp<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <link rel="stylesheet" type="text/css" href="default.css"> </head> <body> <p><a href="controller?action=viewCarList">[Return to List]</a></p> <form method="post" action="controller"> <input type="hidden" name="action" value="saveCar" /> <input type="hidden" name="id" value="${car.id}" /> <table> <!-- input fields --> <tr> <td>Make</td> <td><input type="text" name="make" value="${car.make}" /></td> </tr> <tr> <td>Model</td> <td><input type="text" name="model" value="${car.model}" /></td> </tr> <tr> <td >Model Year</td> <td><input type="text" name="modelYear" value="${car. modelYear}" /></td> </tr> <!-- Save/Reset buttons --> <tr> <td colspan="2"> <input type="submit" name="save" value="Save" /> <input type="reset" name="reset" value="Reset" /> </td> </tr> </table> </form> </body> </html> The JSP pulls the CarDTO from the Request scope and uses it to populate the HTML form. This is less important right now when the CarDTO is in its initial (empty) state. It will become more important when we reuse this form to edit Car information. When the user clicks the "Save" button, the data will be sent back up to the ControllerServlet in Example 5-18 through a saveCar action. Example 5-18. ControllerServlet.java// perform action if(VIEW_CAR_LIST_ACTION.equals(actionName)) { CarDAO carDAO = new HibernateCarDAO( ); request.setAttribute("carList", carDAO.findAll( )); destinationPage = "/carList.jsp"; } else if(ADD_CAR_ACTION.equals(actionName)) { request.setAttribute("car", new CarDTO( )); destinationPage = "/carForm.jsp"; } else if(SAVE_CAR_ACTION.equals(actionName)) { //build the car from the request parameters CarDTO car = new CarDTO( ); car.setMake(request.getParameter("make")); car.setModel(request.getParameter("model")); car.setModelYear(request.getParameter("modelYear")); //save the car CarDAO carDAO = new HibernateCarDAO( ); carDAO.create(car); //prepare the list request.setAttribute("carList", carDAO.findAll( )); destinationPage = "/carList.jsp"; } else { String errorMessage = "[" + actionName + "] is not a valid action."; request.setAttribute(ERROR_KEY, errorMessage); } The saveCar action marshals the name/value parameter pairs from the request into a well-formed CarDTO and calls carDAO.create( ) to save it into the database. Just as we delegated object creation to Hibernate when pulling data from the database, all modern MVC web frameworks will marshal name/value pairs into objects on your behalf as well. Our homegrown MVC framework doesn't offer you this convenience, if only to more clearly demonstrate what is going on under the covers. To give you an idea of what the level of effort would be to use straight JDBC to save your new car to the database, Example 5-19 shows the create( ) method in JDBCCarDAO. Example 5-19. JDBCCarDAO.javapublic void create(CarDTO car) { DataSource dataSource = null; Connection conn = null; PreparedStatement pstmt = null; String insertSql = "insert into CAR(MAKE, MODEL, MODEL_YEAR) values(?,?,?)"; try { dataSource = ServiceLocator.getDataSource(DATA_SOURCE); conn = dataSource.getConnection( ); pstmt = conn.prepareStatement(insertSql); pstmt.setString(1, car.getMake( )); pstmt.setString(2, car.getModel( )); pstmt.setString(3, car.getModelYear( )); pstmt.executeUpdate( ); } catch (Exception e) { System.out.println(e); } finally { try { if(pstmt != null){pstmt.close( );} if(conn != null){conn.close( );} } catch(Exception e) { System.out.println(e); } } } The method accepts a CarDTO, pulls the individual member data out, populates a SQL INSERT statement, and executes the query. Example 5-20 shows the same functionality using Hibernate. Example 5-20. HibernateCarDAO.javapublic void create(CarDTO car) { Session session = null; Transaction tx = null; try { session = ServiceLocator.getHibernateSession(HIBERNATE_SESSION_FACTORY); tx = session.beginTransaction( ); session.save(car); tx.commit( ); } catch (Exception e) { try{tx.rollback( );} catch(Exception e2){System.out.println(e2);} System.out.println(e); } finally { try { if (session != null) {session.close( );} } catch (Exception e) { System.out.println(e); } } } Hibernate handles all the member data wrangling. We simply hand it a CarDTO, and it takes care of the rest.
Add several cars using the HTML form. Use the Ant script in the SQL directory to query the results outside the container. Prove to yourself that no sneaky stuff is going onHibernate is truly inserting the values into the database on our behalf. |