X

Geertjan's Blog

  • November 19, 2005

Struts for the Complete Beginner (Part 4)

Geertjan Wielenga
Product Manager
In the last instalment, you ended up with data access code in a Struts Action class. This is bad. For example, if you read slide 7 of Sang Shin's Accessing Database in Struts Application (which is part of his fantastic—and free—regular college semester-like on-line J2EE course), you're told that "all the database access code should be encapsulated behind the business API classes (using the DAO pattern)". So today I tried to work out what that pattern is all about. The whole theoretical story is described in the Java BluePrints Core J2EE Patterns - Data Access Object.

So, now that it's all working for me, this is what it looks like in the IDE:

These are the files you see listed above:

  • ApplicationResource.properties. The standard Struts localization and messaging file.

  • Customer.java. A POJO representing the customer's name and city (refactored from 'row.java').

  • DAOFactory.java. A factory class that returns PointbaseUserDAO.java:

    public class DAOFactory {
    public static UserDAO createUserDAO(Connection connection){
    return new PointbaseUserDAO(connection);
    }
    }

  • PointbaseUserDAO.java. This is a class that implements UserDAO.java. It is also the class where all my data access code is now found. This is the content:

    public class PointbaseUserDAO implements UserDAO {
    private Connection connection;
    private DataSource dataSource;
    /\*\* Creates a new instance of PointbaseUserDAO \*/
    public PointbaseUserDAO(Connection connection) {
    this.connection = connection;
    }
    public ArrayList listUsers(){
    ArrayList customerList = new ArrayList();
    try{
    String sqlQuery = "SELECT \* FROM CUSTOMER_TBL";
    PreparedStatement prpStmt = connection.prepareStatement(sqlQuery);
    ResultSet rs = prpStmt.executeQuery();
    /\*\* Here we put field 4 (the name) and field 7 (the city) in the customerList: \*/
    while (rs.next()) {
    customerList.add(new Customer(rs.getString(4), rs.getString(7)));
    }
    rs.close();
    } catch ( SQLException e ) {
    System.err.println("SQL Exception occured while accessing the table" );
    e.printStackTrace();
    return null;
    } catch ( Exception e ) {
    e.printStackTrace();
    return null;
    }
    return customerList;
    }
    }

  • SecurityManager.java. A simple file discussed in the first instalment. It forms the basis of what will become a more complex security manager (via a database). Currently, all it does is allow someone called 'Ludwig van Beethoven' to log in with a password 'symphony'.

  • UserAuthenticationAction.java. This is a Struts action (refactored from 'NewStrutsAction.java') that authenticates the user, via the security manager. It now also tells the DAOFactory.java to create an instance of PointbaseUserDAO.java. Here's the relevant part of this file (everything that's new here is in bold):

    if (SecurityManager.AuthenticateUser(newStrutsActionForm.getName(),newStrutsActionForm.getPassword())){dataSource = (DataSource)servlet.getServletContext().getAttribute("custTable");
    Connection conn = dataSource.getConnection();
    UserDAO dao = DAOFactory.createUserDAO(conn);
    customerList = dao.listUsers();
    /\*\* Here we put the customerList in scope, so that we can use it in the JSP page: \*/
    HttpSession session = request.getSession();
    if(customerList != null){
    session.setAttribute("allMyCustomers" , customerList);
    }

    return (mapping.findForward(SUCCESS));
    } else {
    ActionMessages errors = new ActionMessages();
    ActionMessage error = new ActionMessage("errors.login.invalid");
    errors.add("loginWrong",error);
    saveErrors(request.getSession(),errors);
    return mapping.getInputForward();
    }

  • UserDAO.java. This an interface. Currently, it is only implemented by PointbaseUserDAO.java. Theoretically, I could have other implementations—MySQLUserDAO.java, DerbyUserDAO.java, etc. Here's the content (very simple so far):

    public interface UserDAO {
    public ArrayList listUsers();
    }

It's all really kind of nice—a pretty good framework for expanding this application. (By the way, the DataSourceConnectionAction.java from part 3 is now completely empty and can be deleted!) However, one thing puzzles me, and I hope someone knows the answer to this. When you look at UserAuthenticationAction.java above, you still see some data access code. I'd like the datasource to not be created in the Struts Action class—because it contains a reference to a Struts datasource that connects to PointBase. Therefore, this is a PointBase-specific piece of code that shouldn't be in the Struts Action class. Is there any way to move that to the PointbaseUserDAO.java as well?

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.