Enterprise Java Model, View, Controller Web Architecture v050228 MVC 1 First, there were servlets • • • • Enterprise Java And things were good Faster than CGI programs More scalable with built-in threading capability Value-added features – Request/Response, Sessions • Full Java API access – JDBC, JMS, EJB, JavaMail, etc. v050228 MVC 2 Hmm, maybe not so good Enterprise Java • out.printlns in the code became tedious • Takes a programmer to write HTML pages – Skill mismatch • No automated tool support • Mechanisms developed to output HTML pages – Inclusion of pages – htmlKona – Element Construction Set (ECS) • There has to be a better way v050228 MVC 3 Then there were JSPs Enterprise Java • Page-centric view of the world • Limited programmer involvement • JSPs became ubiquitous for dynamic HTML page generation v050228 MVC 4 Model 1 Architecture Java Bean Browser JSP Enterprise Java EJB Database Custom Tags v050228 MVC 5 Model 1 Architecture Enterprise Java • JSP-centric • Suitable for small systems • Susceptible to abuse – Excessive Java code in JSPs – Flow control issues v050228 MVC 6 Hybrid Approach Enterprise Java • Use servlets for flow-control; JSPs for HTML pages with dynamic content • Allows programmer/web designer specialization • Hybrid Approach=Model 2 Architecture • A.K.A. MVC – Controller=Servlet+Helper Classes – Model=Application Data/Operations – View=Output Rendered for User v050228 MVC 7 Model 2 Architecture Enterprise Java 2 EJB Servlet 3 1 Browser 4 Java Bean Database 5 6 JSP Custom Tags v050228 MVC 8 Model 2 Benefits Enterprise Java • Allows programmer to implement flow control, system operations in Java/Servlets • Allows web page designers to develop HTML/JSP pages – Automated tool support • Higher degree of re-use; more maintainable architecture for larger systems v050228 MVC 9 Struts Enterprise Java • ‘Standard’ MVC framework • Struts 1.0 released in January 2001 • MVC architecture with support for: – – – – v050228 Configurable site navigation Form handling Internationalization Extensive Custom tag libraries MVC 10 Enterprise Java Struts Architecture Action Mappings 2 Browser 8 1 3 ActionServlet Database Action 4 Bean 6 5 7 View (Servlet/JSP/HTML) v050228 MVC 11 Struts Application Flow Enterprise Java • All requests are first processed by the action servlet • Refers to ActionMappings to determine action to invoke – Calls Actions you’ve implemented for your application – Should be adapters to the rest of the application • Action returns view to forward to • View renders data placed in request or session scope by Action class v050228 MVC 12 A corej2ee MVC-light Enterprise Java • Struts and similar solutions provide for robust solutions – should be considered for most real implementations – Too little time to cover the details in this course • Introduce MVC using a smaller-scale implementation – based on same similar MVC concepts – functional, but does not cover full array of issues involved in a Web-based development • its simplicity makes understanding the MVC components possible within the scope of this course v050228 MVC 13 corej2ee.web Interfaces/Classes HttpServlet Controller +PRINT_DEBUG:boolean +DEBUG_PREFIX:String +NAVIGATION_CLASS:String +UNKNOWN_URI:String +EVENT_CONTEXT:String +EVENT:String -navigation_:Navigation -unknownUri_:String +init:void +doGet:void +doPost:void #debug:void servletInfo:String interface interface interface Navigation Route Worker +getRoute:Route +getNextPage:String worker:Worker +SUCCESS:String +ERROR:String +RESULT:String +ERROR_MESSAGE:String +execute:Object EnvEntryNavigator +PRINT_DEBUG:boolean +DEBUG_PREFIX:String +ROUTE_CONTEXT:String #routes_:Map +EnvEntryNavigator +init:void +getRoute:Route #buildRoute:Route +toString:String #debug:void v050228 Enterprise Java MVC BasicRoute -worker_:Worker -successUri_:String -failUri_:String +BasicRoute +getNextPage:String +toString:String NullWorker +execute:Object worker:Worker 14 corej2ee.web.Controller Enterprise Java public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ v050228 String path=request.getServletPath(); try { Route route = navigation_.getRoute(path); String uri = unknownUri_; if (route != null) { Worker worker = route.getWorker(); Object result = worker.execute( getServletContext(),request,response); uri = route.getNextPage(result); } RequestDispatcher rd = getServletContext().getRequestDispatcher(uri); if (rd != null) { rd.forward(request, response); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND, "unable to locate uri '" + uri + "' while handling path '" + path + "'"); } } MVC 15 corej2ee.web.EnvEntryNavigator web.xml Configuration Enterprise Java <!-- begin: listPrincipals 1 --> <env-entry> <env-entry-name>route/content-listPrincipals1/worker</env-entry-name> <env-entry-value>corej2ee.examples.principal.web.GetPrincipalsDAOWorker </env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry> <env-entry> <env-entry-name>route/content-listPrincipals1/success</env-entry-name> <env-entry-value>/WEB-INF/content/showResult.jsp</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry> <env-entry> <env-entry-name>route/content-listPrincipals1/fail</env-entry-name> <env-entry-value>/WEB-INF/content/ErrorPage.jsp</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> v050228 </env-entry> MVC 16 corej2ee.web.EnvEntryNavigator web.xml Configuration Enterprise Java <!-- begin: listPrincipals 2 --> <env-entry> <env-entry-name>route/content-listPrincipals2/worker</env-entry-name> <env-entry-value>corej2ee.examples.principal.web.GetPrincipalsDAOWorker </env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry> <env-entry> <env-entry-name>route/content-listPrincipals2/success</env-entry-name> <env-entry-value>/WEB-INF/content/printPrincipals.jsp</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry> <env-entry> <env-entry-name>route/content-listPrincipals2/fail</env-entry-name> <env-entry-value>/WEB-INF/content/ErrorPage.jsp</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> v050228 </env-entry> MVC 17 corej2ee.examples.principal.web Workers Worker PrincipalDAOWorker +PRINT_DEBUG:boolean +DEBUG_PREFIX:String -DB_NAME:String connectionBean_:ConnectionBean principalDAO_:PrincipalDAO +PrincipalDAOWorker #closeConnection:void #getPrincipalType:String #getPrincipal:Principal #log:void Enterprise Java interface corej2ee.web.Worker +SUCCESS:String +ERROR:String +RESULT:String +ERROR_MESSAGE:String +execute:Object connection:Connection DAO:PrincipalDAO GetPrincipalsDAOWorker GetPrincipalDAOWorker InsertPrincipalDAOWorkerModifyPrincipalDAOWorker +GetPrincipalsDAOWorker +GetPrincipalDAOWorker +InsertPrincipalDAOWorker +ModifyPrincipalDAOWorker +execute:Object +execute:Object +execute:Object +execute:Object v050228 MVC 18 corej2ee.examples.principal.web. GetPrincipalsDAOWorker Enterprise Java public Object execute(ServletContext context, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = null; try { conn = getConnection(); Collection principals = getDAO().findByWhere(conn, "1=1"); request.setAttribute(RESULT, principals); return SUCCESS; } catch (Exception ex) { request.setAttribute(ERROR_MESSAGE, ex.toString()); return ERROR; } finally { closeConnection(conn); } } v050228 MVC 19 principalWEB showResult.jsp Enterprise Java <jsp:directive.page errorPage="/ExceptionPage.jsp" /> <jsp:directive.page import="corej2ee.web.*" /> <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <title>Show Result</title> </head> <body> <center><h1>Results</h1></center> <%=request.getAttribute(Worker.RESULT)%> </body> </html> v050228 MVC 20 principalWEB showResult.jsp v050228 MVC Enterprise Java 21 principalWEB printPrincipals.jsp <jsp:directive.page errorPage="/ExceptionPage.jsp" /> <jsp:directive.page import="corej2ee.examples.principal.*" /> <jsp:directive.page import="corej2ee.web.*" /> <html> <head> <title>List Principals</title> </head> <body> <center><h1>Principals</h1></center> <nl> <jsp:scriptlet> Collection principals = (Collection)request.getAttribute(Worker.RESULT); for(Iterator itr=principals.iterator(); itr.hasNext(); ) { </jsp:scriptlet> <li><jsp:expression>itr.next()</jsp:expression></li> <jsp:scriptlet> } </jsp:scriptlet> </nl> </body> v050228</html> MVC Enterprise Java 22 principalWEB printPrincipals.jsp v050228 MVC Enterprise Java 23 Resources Enterprise Java • http://jakarta.apache.org/struts/ • http://jguru.com/faq/Struts • http://jguru.com/forums/home.jsp?topic=Struts v050228 MVC 24