package net.titaniclinux.daogen.examples; import java.io.*; import java.util.*; import java.text.*; import java.sql.*; import javax.servlet.*; import javax.servlet.http.*; public class Example3 extends HttpServlet { private ServletConfig config; private ServletContext context; private CustomerDao customerHandler; private String jdbcDriver; private String jdbcUrl; private String jdbcLogin; private String jdbcPasswd; public void init(ServletConfig servletConfig) throws ServletException { // Store initial servlet configuration: config = servletConfig; context = config.getServletContext(); // Database Connection information. In real applications the database // connections are usually pooled and these connection parameters are // not hard-coded, but instead configurable in properties files or // web.xml files. However, for simplicity we keep them here now. jdbcDriver = "jdbc:mysql"; jdbcUrl = "localhost/test"; jdbcLogin = "username"; jdbcPasswd = "password"; try { // If you do not use MySQL database, you need to change the MySQL // driver to your own JDBC database driver. (See the line below:) DriverManager.registerDriver(new org.gjt.mm.mysql.Driver()); } catch (SQLException error) { System.out.println(error.toString()); throw new ServletException(error.toString()); } // Create the DAO component instance. This object can be created // easily, since the constructor takes no arguments. We will need // the Database resources (Connection) only when we want to actually // use this DAO for something. Note: All DAO classes that are generated // with DaoGen are thread safe! This means, that for multi threaded // programs (like HttpServlets) you need to create only one instance // and you can then share it for all requests (threads). The advantage // of doing so is that your programs will use less memory. customerHandler = new CustomerDao(); } public void destroy() { System.out.println("Example servlet is shutting down."); } public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // This servlet will handle all requests the same way: doPost (request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get the database connection from helper method: Connection conn = this.getNewConnection(); try { // First, load all customers from database. This can be done, // if the amount of customers is not huge. In this example we // expect to have only few customers, so we have no problem. You can // also use countAll() method before loadAll() to make sure you // are not loading too many records. List allCustomers = customerHandler.loadAll(conn); // Check if user actually did press the submit button in the // page. If not, we can just skip this part and proceed to jsp. if (request.getParameter("saveChanges") != null) { // Now, loop trough the customerlist and make modifications // when needed. We may also remove some customers here. // NOTE: You do not have do the updates this way, you can also // load customers one be one and update them, but in this case // this is the most efficient and simple way to do it. for (int i=0; i < allCustomers.size(); i++) { Customer tempCustomer = (Customer)allCustomers.get(i); if (request.getParameter("delete-" + tempCustomer.getNumber()) != null) { // If user did press the "Delete customer" button, we will // just delete this record and remove it from the list. customerHandler.delete(conn, tempCustomer); allCustomers.remove(tempCustomer); } else { // For most customers, the delete was not activated (hopefully ;) // so we just update the records. Note how simple it is - the most // difficult part is the String to int conversion (which is easy)! tempCustomer.setAddress(request.getParameter("address-" + tempCustomer.getNumber())); int tempBalance = 0; try { tempBalance = Integer.parseInt(request.getParameter("balance-" + tempCustomer.getNumber())); } catch (NumberFormatException badBalance) { } tempCustomer.setBalance(tempBalance); // This one line will update the database: customerHandler.save(conn, tempCustomer); } } // This servlet application can also handle new customer accounts. If all needed // information was submitted, we will create the new customer and add it to list. String newNumber = request.getParameter("number-new"); String newName = request.getParameter("name-new"); String newAddress = request.getParameter("address-new"); String newBalance = request.getParameter("balance-new"); if (newNumber != null && newName != null && newAddress != null && !newNumber.equals("") && !newName.equals("") && !newAddress.equals("") && !newBalance.equals("")) { int tempBalance = 0; int tempNumber = 1; try { tempNumber = Integer.parseInt(newNumber); tempBalance = Integer.parseInt(newBalance); } catch (NumberFormatException badNumbers) { } Customer newCustomer = new Customer(tempNumber); newCustomer.setName(newName); newCustomer.setAddress(newAddress); newCustomer.setCreated(new java.sql.Date(System.currentTimeMillis())); newCustomer.setBalance(tempBalance); try { // This is convenient way for finding out if given primary key is // already used. Just try to load the object with the primary key set // and if load throws NotFoundException, primary key is ok. However // if load succeeds, then we need to get a new primary key. customerHandler.load(conn, newCustomer); request.setAttribute("message", "You must give customer number which is unique!"); } catch (NotFoundException ok) { customerHandler.create(conn, newCustomer); allCustomers.add(newCustomer); } } } // Set the Request attribute, so that we can access the data in JSP. // The allCustomers list contains now the value objects for all records // in database, but these value objects are completely detached from the // database and we can handle this list without even knowing about JDBC // and the overhead of database queries. request.setAttribute("customerList", allCustomers); } catch (NotFoundException notFound) { System.out.println(notFound.toString()); throw new ServletException(notFound.toString()); } catch (SQLException error) { System.out.println(error.toString()); throw new ServletException(error.toString()); } finally { // Whatever happens, close the opened connection. This does not affect // the Value Objects that are already loaded in runtime memory. this.closeConnection(conn); } // Finally, forward the request to JSP page for presentation. // You should never code the html inside your servlets, and even // this is the most simple servlet example, we avoid it too! response.setContentType("text/html"); RequestDispatcher reqd = context.getRequestDispatcher("/customer-edit.jsp"); reqd.include(request, response); } /** * Private methods for handling Database Connection. This is the most simple way * to use the connection, but it has several drawbacks. The connections are not * pooled, and so the performance suffers. Also, this is considered as an old-style * way for handling connection, as all new application servers support convenient * pooled datasources. However, their configuration can be difficult to understand * for newbies, so this simplistic way should be enough for this example program. */ private Connection getNewConnection() throws ServletException { try { // Now we use the DriverManager to get the connection to Database: Connection conn = DriverManager.getConnection (jdbcDriver + "://" + jdbcUrl, jdbcLogin, jdbcPasswd); return conn; } catch (Exception error) { System.out.println("Database connection can not be created!"); System.out.println("Error description: " + error.toString()); throw new ServletException(error.toString()); } } private void closeConnection(Connection conn) { try { // Close the database connection. conn.close(); } catch (Exception error) { System.out.println("Error when closing Database connection!"); } } }