v Web Tier Architecture MVC and Struts
v First, there were servlets 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.
v Hmm, maybe not so good 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
v Then there were JSPs Page-centric view of the world Limited programmer involvement JSPs became ubiquitous for dynamic HTML page generation
v Model 1 Architecture Browser JSP Java Bean Database Custom Tags EJB
v Model 1 Architecture JSP-centric Suitable for small systems Susceptible to abuse –Excessive Java code in JSPs –Flow control issues
v Hybrid Approach 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
v Model 2 Architecture Browser JSP Java Bean Database Custom Tags EJB Servlet
v Model 2 Benefits 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
v Struts ‘Standard’ MVC framework Struts 1.0 released in January 2001 MVC architecture with support for: –Configurable site navigation –Form handling –Internationalization –Extensive Custom tag libraries
v Struts Architecture Browser ActionServlet Action Mappings Action Database Bean View (Servlet/JSP/HTML)
v Application Flow 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
v Hello Struts Application Create an action to place a ‘HelloBean’ in the request scope Create view that renders the HelloBean Configure ActionServlet to map request to the HelloAction Configure and Deploy
v Hello Action package corej2ee.project.strutsHello; import org.apache.struts.action.*; import javax.servlet.http.*; public class HelloAction extends Action { public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp) { req.setAttribute("HelloBean", new HelloBean()); return mapping.findForward("showMessage"); }
v Hello Bean package corej2ee.project.strutsHello; public class HelloBean { String message; public HelloBean() { message="Struts Hello"; } public void setMessage(String m) { message=m; } public String getMessage() { return message; }
v showMessage.jsp <jsp:useBean id="HelloBean" scope="request" class="corej2ee.project.strutsHello.HelloBean" /> Message is:
v Configure Action Servlet <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN" " <action path="/hello" type="corej2ee.project.strutsHello.HelloAction">
v Configure web.xml strutsHello action org.apache.struts.action.ActionServlet config /WEB-INF/struts-config.xml debug 2 2 action *.do
v /WEB-INF/struts-bean.tld /WEB-INF/struts-html.tld /WEB-INF/struts-logic.tld /WEB-INF/struts-template.tld
v ANT Build <war warfile="${strutsHello_war}" webxml="corej2ee/project/strutsHello/WEB-INF/web.xml">
v Deployment (From Docs) Copy the file lib/struts.jar from the Struts distribution into the WEB-INF/lib directory of your web application. Copy the all of the files that match lib/struts*.tld from the Struts distribution into the WEB-INF directory of your web application. Modify the WEB-INF/web.xml file for your web application to include a element to define the controller servlet, and a element to establish which request URIs are mapped to this servlet. Use the WEB-INF/web.xml file from the Struts example application for a detailed example of the required syntax
v Deployment (Cont.) Modify the WEB-INF/web.xml file of your web application to include the following tag library declarations: /WEB-INF/struts-bean.tld /WEB-INF/struts-html.tld /WEB-INF/struts-logic.tld /WEB-INF/struts-template.tld
v Deployment (Cont) Create a file WEB-INF/struts-config.xml that defines the action mappings and other characteristics of your specific application. You can use the struts-config.xml file from the Struts example application for a detailed example of the required syntax. At the top of each JSP page that will use the Struts custom tags, add line(s) declaring the Struts custom tag libraries used on this particular page, like this:
v Resulting War File C:\COREJ2EE\DEVROOT\BUILD\LIB>jar tvf strutsHello.war 0 Mon Mar 11 17:45:50 EST 2002 META-INF/ 48 Mon Mar 11 17:45:50 EST 2002 META-INF/MANIFEST.MF 0 Mon Mar 11 17:45:50 EST 2002 WEB-INF/ 0 Mon Mar 11 17:45:50 EST 2002 WEB-INF/lib/ Mon Mar 11 17:45:48 EST 2002 WEB-INF/lib/util.jar Fri Jan 11 16:34:44 EST 2002 WEB-INF/lib/struts.jar 0 Mon Mar 11 17:45:50 EST 2002 WEB-INF/classes/ 0 Mon Mar 11 17:45:50 EST 2002 WEB-INF/classes/corej2ee/ 0 Mon Mar 11 17:45:50 EST 2002 WEB-INF/classes/corej2ee/project/ 0 Mon Mar 11 17:45:50 EST 2002 WEB-INF/classes/corej2ee/project/strutsHello/ 742 Mon Mar 11 17:45:50 EST 2002 WEB-INF/classes/corej2ee/project/strutsHello/HelloAction.class 362 Mon Mar 11 17:45:50 EST 2002 WEB-INF/classes/corej2ee/project/strutsHello/HelloBean.class 500 Mon Mar 11 17:27:16 EST 2002 WEB-INF/struts-config.xml 0 Mon Mar 11 17:36:12 EST 2002 WEB-INF/WEB-INF/ 8101 Fri Jan 11 16:34:44 EST 2002 WEB-INF/WEB-INF/struts-bean.tld Fri Jan 11 16:34:44 EST 2002 WEB-INF/WEB-INF/struts-form.tld Fri Jan 11 16:34:44 EST 2002 WEB-INF/WEB-INF/struts-html.tld Fri Jan 11 16:34:44 EST 2002 WEB-INF/WEB-INF/struts-logic.tld 1637 Fri Jan 11 16:34:44 EST 2002 WEB-INF/WEB-INF/struts-template.tld Fri Jan 11 16:34:44 EST 2002 WEB-INF/WEB-INF/struts.tld 224 Mon Mar 11 17:23:14 EST 2002 showMessage.jsp 1516 Mon Mar 11 17:38:20 EST 2002 WEB-INF/web.xml
v041003
Controller The Controller (ActionServlet) decides ‘what needs to be done’ Uses configuration to determine actions that should be called <action path="/hello" type="corej2ee.project.strutsHello.HelloAction"> We configured all URLs ending in *.do to be first processed by the controller
v Actions Invoked by the action servlet and determines ‘how to get it done’ Typically performs operation (database update, retrieval) and places result information in the request or session Returns ActionForward instance to control next page to forward control to Note: Implementation must be thread-safe
v Action class
v Action Forward Typically use logical name for target page Local targets defined for action <action path="/hello" type="corej2ee.project.strutsHello.HelloAction"> public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp) { req.setAttribute("HelloBean", new HelloBean()); return mapping.findForward("showMessage"); } Allows view pages to be renamed with little impact
v Action Forward (Cont) Global forwards for application <global-forwards type="org.apache.struts.action.ActionForward"> <forward name="showMessageGlobal" path="/showMessageGlobal.jsp" redirect="false" /> public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp) { req.setAttribute("HelloBean", new HelloBean()); return mapping.findForward("showMessageGlobal"); } Defines forwards that can be accessed by all actions
v View Renders beans placed into session or request by actions We used jsp:useBean in showMessage.jsp Many custom tags are available in Struts to simplify this task –Covered in more detail later
v Form Handling Most web applications use HTML Forms Struts can automatically populate a Java Bean (Form Bean) with data submitted –Similar to jsp:setProperty with an ‘*’ parameter Form Beans are associated with an action –Form bean is updated before action is invoked Form Beans are configured in struts- config.xml
v Form Processing Flow Action Servlet Form Bean Action Results JSP Page 1. submit 2. populate 3. perform 4. use 5. create 6. forward 8. HTML results 7. use
v Document Form Bean package corej2ee.project.strutsHello; import org.apache.struts.action.ActionForm; public class DocumentFormBean extends ActionForm { String documentCategory; String documentContent; public void setDocumentCategory(String cat) { documentCategory=cat; } public String getDocumentCategory() { return documentCategory; } public void setDocumentContent(String content) { documentContent=content; } public String getDocumentContent() { return documentContent; }
v struts-config.xml <form-bean name="DocumentForm" type="corej2ee.project.strutsHello.DocumentFormBean" /> …….. <action path="/submitDocument" type="corej2ee.project.strutsHello.DocumentAction" name="DocumentForm" scope="request" input="/showSubmitDocument.jsp" validate="false" />
v Document Action Gets the populated form bean and sets an attribute so success page can display values public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp) { DocumentFormBean dfb=(DocumentFormBean) form; req.setAttribute("message", dfb.toString()); return mapping.findForward("success"); }
v Success.jsp success.jsp Message is:
v showSubmitDocument.jsp Category Content
v041003
Struts custom HTML tags Can simplify JSP pages that present forms Particularly helpful for handling incomplete form submissions –We’ll see this after the Internationalization section Let’s work on showSubmitDocument.jsp…
v Category: Content: Submit Reset
v Internationalization Key Java Classes –java.util.Locale –java.util.ResourceBundle –java.util.PropertyResourceBundle –java.text.MessageFormat Struts classes –org.apache.struts.util.MessageResources –Allows caller to retrieve resource for a specified locale
v Steps Define property files for each supported locale Configure ActionServlet with base name of application’s resource bundle Optionally, configure action servlet to set Locale object based on browser request headers Set locale object in session for user –session.setAttribute(Action.LOCALE_KEY, locale); Display resource strings
v Resource Bundles Must be placed in the web application’s classpath StrutsHello.properties –prompt.hello=hello StrutsHello_fr.properties –prompt.hello=salut
v Request Header Configuration Action Servlet can automatically set Locale object in user’s session based on browser request header Set the servlet initialization parameter ‘locale’ to true –Stored in session at Action.LOCALE_KEY –Only if locale object is not already there
v Configure web.xml action org.apache.struts.action.ActionServlet config /WEB-INF/struts-config.xml debug 2 application StrutsHello 2 Set resources
v Display Resource Strings MessageResources.getMessage(…) Bean Custom tag –
v SetLocaleAction public class SetLocaleAction extends Action { public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp) { HttpSession s=req.getSession(true); if("fr".equals(req.getParameter("L"))) { s.putValue(Action.LOCALE_KEY, Locale.FRANCE); } else { s.putValue(Action.LOCALE_KEY, Locale.US); } return mapping.findForward("SubmitDocument"); }
v Basic Page to set Locale I18n message: Category: Content: Submit Reset Set Locale:
v041003
Error Processing Form Bean can implement validate() method –Return ActionErrors if input is not valid –Controller will forward back to the input form that submitted the form –Input Form page redisplays form with errors highlighted Should always do as much validation as possible in the browser with JavaScript –Better performance
v DocumentFormBean public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { if("badCategory".equals(documentCategory)) { ActionErrors ae=new ActionErrors(); ae.add("documentCategory", new ActionError("prompt.badcategory", "")); return ae; } else { return null; }
v prompt.hello=hello prompt.badcategory=You must enter a valid category prompt.hello=salut prompt.badcategory=You must be an American - bad category
v041003
Utilities Connection Pool –Can create a datasource –DataSource ds=servlet.findDataSource() Digester –XML processing utility File Upload Capability
v Struts Summary Well-thought out Model 2 Framework Strengths –Form Handling –Internationalization –Configurable navigation
v Resources uts