05 - mvc with struts - mvc with struts.pdf · 1 cse 135 the mvc design pattern & the struts...
TRANSCRIPT
1
CSE 135
The MVC Design Pattern &The Struts Framework
for every JSP page pfor every type of request r to p
insert in p code to implement the action requested by r
Previous Attempts:Model 1 Design Pattern
Messy JSP!
Messy JSP!
students.jspIf request to insert student
perform SQL INSERTIf request to delete student
perform SQL UPDATEIf request to update student
perform SQL DELETE
2
http://.../students.jsp?action=insert&...
perform SQL DELETE
HTML part of the JSPINSERT STUDENTUPDATE STUDENTDELETE STUDENT
http://.../students.jsp?action=update&...
http://.../students.jsp?action=delete&...
2
The MVC Design Pattern:Separating Model, View & Controller
View
• Development “Best Practice”
Control unit 2Control unit 1
View
Controller
BrowsableWeb/ multi-device
applications
• Known well before web items– Smalltalk pioneered
• Model: Access to Underlying Databases and Info Sources
3
Databases
Model• Controller: Control Flow of Web App
• View: Look-and-Feel
The MVC Design Pattern
• MVC originated as Model 2 in web developers community
• Model 1: Application logic is attached to JSPs– Similar to previous attempts of students.jsp
• Model 2: Data access and control flow decisions in Java Beans
4
3
Data Entry Example – MVC Attempt
students.jsp
HTML part of the JSPINSERT STUDENT
View
INSERT STUDENTUPDATE STUDENTDELETE STUDENT
Insert Student
UpdateStudent
Delete Student
Controller/Actions
5
DB
Model Java classes export methods that encapsulate SQL accessModel
The Process and the Frictions
Analysis/S ifi i
Business Process Owner (Client)
COMMUNICATIONbusiness process T get of Ph e 1Specification
Phase
DevelopmentPhase
Chief Architect/Technical Project Leader
business process and specification of Web application
COMMUNICATION technical specification
Target of Phase 1
Target of Phase 3
6
Phase pand development
Developer
Problem is even worse in evolution phase when application logic is hidden in thousands of lines of code
4
Struts
• Black-Box Framework Implementing MVC– Framework: reusable “partial” application
St t id hi h l l t l • Struts ActionServlet provides high level control of workflow (i.e., “what happens next”)
• You provide Beans and files to customize framework according to your application needs1. JSPs provide HTML presentation (View)2. ActionForm Beans “collect” form data (Part of Controller)
7
3. Action Beans provide details of flow (Part of Controller)4. struts-config.xml declares Beans and JSPs
How To Develop Struts Applications
From 10 Miles High:• Pass high-level control to ActionServlet
– By appropriate URL mapping in web.xml
• Design “workflow” in diagrams and then code it in struts-config.xml
• Develop ActionForm Beans responsible for collecting data
• Develop Action Beans responsible for changing
8
p p g gthe state of the application and deciding next step
• Develop Model Beans (not part of Struts) responsible for encapsulating database access
• Develop HTML and JSP pages for user interface
5
ViewView
Struts application lifetime: How is a browser request processed?
ActionForward(Page or Action)
Request/SessionScopeRequest/SessionScope
DataDataget
ActionFormActionForm
HTTP Request ModelBean
ActionServlet
ActionAction2
3
567
HTTP Response
InitiatingPage
4Form Validation
set
9
ModelModel
ControllerController
struts‐config.xml
DB
1Error
Struts Single Request Processing (cont’d)
• When web app is loaded, ActionServlet parses struts-config.xml and associates URL paths with A ti and A ti F Beans
1
with Action and ActionForm Beans– Location of struts-config.xml is given in web.xml
• The user issues an HTTP request from an initiating page P to the ActionServlet
2
10
6
Struts Single Request Processing (cont’d)
• The ActionServlet instantiates the ActionFormBean associated with the HTTP request URL in t t fi l and sets its properties
3
struts-config.xml, and sets its properties using the HTTP request parameters (user-submitted data)
• The ActionForm Bean validates its property values and if validation fails, ActionServletresponds with the initiating page P displaying appropriate error messages for the user to
4
11
appropriate error messages for the user to correct his/her form data
Struts Single Request Processing (cont’d)
• If validation succeeds, the ActionServletinstantiates the Action Bean associated with the HTTP request URL in t t fi l and
5
HTTP request URL in struts-config.xml, and calls its execute method passing as parameters the ActionForm Bean, the HTTP request and the HTTP response objects
12
7
Struts Single Request Processing (cont’d)
• Within its execute method, the Action Bean instantiates/calls Model Beans, which open a connection to the database execute SQL
6
connection to the database, execute SQL operations, and return sets of tuplesThe Action Bean places the sets of tuples in the session so that JSP pages (View components) can access them
13
Struts Single Request Processing (cont’d)
• The Action Bean returns to the ActionServletone of the ActionForwards with which the HTTP request URL is associated in t t fi l
7
request URL is associated in struts-config.xmlAn ActionForward is a possible outcome of the Action Bean and represents either an JSP/HTML page or another Action that will be the response to the user’s requestUpon receiving the ActionForward, the
d t th ’ t
14
ActionServlet responds to the user’s request with the corresponding JSP/HTML page or Action
8
Install Struts
• We will use Struts 1.3 for Phase 2 of the project– Struts 2 will be covered later on and will not be used
for the projectfor the project• Download struts-1.3.10-all.zip• Struts is only a package containing:
\doc, \src, \lib, \apps• Within \apps is a set of *.war files
– struts-blank-1.3.10.war
15
– struts-examples-1.3.10.war– struts-cookbook-1.3.10.war
Struts Examples
• To play with Struts examples:– Copy struts-cookbook-1.3.10.war under \webapps
A htt //l lh t 8080/ t t kb k 1 3 10/– Access http://localhost:8080/struts-cookbook-1.3.10/• To play with more Struts examples:
– Copy struts-examples-1.3.10.war under \webapps– This automatically deploys a new web app directory– Access http://localhost:8080/struts-examples-1.3.10/
• To start your own Struts application:
16
– Copy struts-blank-1.3.10.war under \webapps– Rename \struts-blank-1.3.10 to \your_app_name
9
Pass Control to ActionServlet
web.xmll
URLs of requests ending with “.do”, pass all .do requests to ActionServlet
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
l d 2 /l d
17
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Let’s reconsider the “students” example
18
10
Data Entry Example - 7th Attempt
Web Application Workflow
Students(hyperlink)
menu.jsp
success
success !validate
!validate
students.jspshowStudents.doshowStudents.do
insertStudent.doinsertStudent.do
StudentFormInsertUpdateStudentFormInsertUpdate
StudentFormInsertUpdateStudentFormInsertUpdate StudentForm
DeleteStudentForm
Delete
Insert(button)
Update(button)
Delete(button)
19
success
success
updateStudent.doupdateStudent.do
deleteStudent.dodeleteStudent.do
Data Entry Example - 7th Attempt
Web AppliationWorkflow
Students(hyperlink)
menu.jsp
set getRequest ScopeRequest Scope
StudentsRowSetStudentsRowSet
success
success !validate
!validate
students.jspshowStudents.doshowStudents.do
insertStudent.doinsertStudent.do
StudentFormInsertUpdateStudentFormInsertUpdate
StudentFormInsertUpdateStudentFormInsertUpdate StudentForm
DeleteStudentForm
Delete
Insert(button)
Update(button)
Delete(button)
20
success
success
updateStudent.doupdateStudent.do
deleteStudent.dodeleteStudent.do
StudentModel.getAllStudents()(SELECT * FROM Students)
StudentModel.insertStudent()(INSERT INTO Students…)
StudentModel.updateStudent()(UPDATE Students…)
StudentModel.deleteStudent()(DELETE FROM Students…)
DB
11
ViewView
showStudents.do Request Processing
students.jsp getRequest ScopeRequest Scope
StudentsRowSetStudentsRowSet
ControllerController
…/showStudents.doStudentModelActionServlet ShowStudentsActionShowStudentsAction
success
menu.jsp
set
2
3
5
4
21
ModelModelstruts‐config.xml
DB1
showStudents.do Configuration
struts-config.xml<struts-config>
...
<action-mappings>
<action
path="/showStudents"
type="dataentry.actions.ShowStudentsAction">
<forward
name="success”
path "/pages/students jsp"/>
22
path="/pages/students.jsp"/>
</action>
...
</action-mappings>
...
</struts-config>
12
showStudents.do Action Bean
ShowStudentsAction.javapackage dataentry.actions;
import javax.sql.RowSet;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import dataentry.model.StudentModel;
...
23
public class ShowStudentsAction extends Action {
...
showStudents.do Action Bean
ShowStudentsAction.java (cont’d)...
public ActionForward execute(public ActionForward execute(
ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws DBException {
// retrieve all students
RowSet crsStudents = StudentModel.getAllStudents();
// t th R S t i th t
24
// store the RowSet in the request scope
request.setAttribute("crsStudents", crsStudents);
return mapping.findForward("success");
}
}
13
showStudents.do Model Bean
StudentsModel.javapackage dataentry.model;
...
public class StudentModel {
private static String selectStr = ...;
private static String insertStr = ...;
private static String updateStr = ...;
private static String deleteStr = ...;
public static CachedRowSet getAllStudents() { }
25
public static CachedRowSet getAllStudents() {...}
public static void insertStudent(StudentBean student) {...}
public static void updateStudent(StudentBean student) {...}
public static void deleteStudent(StudentBean student) {...}
}
showStudents.do ActionForward
students.jsp<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
...
<%-- -------- Iteration Code -------- --%>
<% RowSet crsStudents = (RowSet) request.getAttribute("crsStudents");
while (crsStudents.next()) { %>
<tr>
...
<td>
<html:text property=”middle" size="15"
26
p p y
value="<%=crsStudents.getString(\”middleName\")%>" />
</td>
...
</tr>
<% } %>
...
14
ViewView
insertStudent.do Request Processing
showStudents.do(Step on Slide 8)2
StudentFormInsertUpdateStudentFormInsertUpdate
…/insertStudent.do StudentModel
ActionServlet
InsertStudentActionInsertStudentAction
success
students.jsp
Form ValidationError
2 5 6
7
4
27
ModelModel
ControllerController
struts‐config.xml
DB
rror
1 34
insertStudent.do Configuration
struts-config.xml...
<form bean name="studentFormInsertUpdate”<form-bean name="studentFormInsertUpdate”
type="dataentry.forms.StudentFormInsertUpdate"/>
...
<action
path="/insertStudent”
type="dataentry.actions.InsertStudentAction"
validate="true”
scope "request"
28
scope="request"
input="/showStudents.do”
name="studentFormInsertUpdate">
<forward name="success" path="/showStudents.do”
redirect="true"/>
</action>
15
insertStudent.do ActionForm Bean
StudentFormInsertUpdate.java
package dataentry forms;package dataentry.forms;
...
public class StudentFormInsertUpdate extends ActionForm {
private String id = null;
private String first = null;
private String middle = null;
i t St i l t ll
29
private String last = null;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
...
insertStudent.do ActionForm Bean
StudentFormInsertUpdate.java (cont’d)
...
/**
* Reset all properties to their default values.
*/
public void reset(ActionMapping mapping,
HttpServletRequest request) {
setId(null);
tFi t( ll)
30
setFirst(null);
setMiddle(null);
setLast(null);
}
...
16
insertStudent.do ActionForm Bean
StudentFormInsertUpdate.java (cont’d)...
public ActionErrors validate(ActionMapping mappingpublic ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if ((id == null) || (id.length() < 1))
errors.add("idMsgTag1",
new ActionMessage("errors required" ”ID"))
31
new ActionMessage("errors.required", ”ID"));
...
return errors;
}
}
insertStudent.do Action Bean
InsertStudentAction.javapublic class InsertStudentAction extends Action {
public ActionForward execute(ActionMapping mappingpublic ActionForward execute(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws DBException {
// cast the form
StudentFormInsertUpdate iForm =
(StudentFormInsertUpdate) form;
// i t th t d t
32
// insert the student
StudentModel.insertStudent(iForm);
return mapping.findForward("success");
}
}
17
insertStudent.do ActionForward
students.jsp<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
...The corresponding A i F b<!-- in case form validation fails -->
<html:errors />
...
<tr>
<html:form action="/insertStudent">
<td><html:text property="id" size="10" /></td>
<td><html:text property="first" size="15" /></td>
<td><html:text property="middle" size="15" /></td>
ActionForm bean will also be used to populate HTML
form
33
<td><html:text property middle size 15 /></td>
<td><html:text property="last" size="15" /></td>
<td><html:submit value="Insert" /></td>
<td><html:reset /></td>
</html:form>
</tr>
...
struts-config.xml Structure
<struts-config><!-- ========================= Form Bean Definitions --><form-beans>...</form-beans>
<!-- ================== Global Exception Definitions --><global-exceptions>...</global-exceptions>
<!-- ==================== Global Forward Definitions --><global-forwards>...</global-forwards>
34
<!-- ==================== Action Mapping Definitions --><action-mappings>...</action-mappings>
<!-- ================= Message Resources Definitions --><message-resources parameter="MessageResources" />
</struts-config>
18
Global Exceptions
struts-config.xml
<! ==================== Global Exception Definitions ><!-- ==================== Global Exception Definitions -->
<global-exceptions>
<exception key="error.db"
type="dataentry.db.DBException"
path="/pages/dbException.jsp"/>
</global-exceptions>
35
Global Exceptions
DBException.java
package dataentry db;package dataentry.db;
public class DBException extends Exception {
public DBException() {
super();
}
36
public DBException(String message) {
super(message);
}
}
19
Global Exceptions
StudentModel.java
public static void insertStudent(public static void insertStudent(
StudentFormInsertUpdate student) throws DBException {
try {
...
} catch (SQLException ex) {
throw new DBException(ex);
} catch (NamingException ex) {
37
} catch (NamingException ex) {
throw new DBException(ex);
}
}
Global Exceptions
InsertStudentAction.java
public class InsertStudentAction extends Action {public class InsertStudentAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws DBException {
...
StudentModel.insertStudent(...);
38
...
}
}
20
Global Exceptions
dbException.jsp
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<body>
<h2>Database Exception</h2>
...
<h3>Here is the message generated by the thrown database
exception:</h3>
39
<p><html:errors /></p>
</body>
</html>
Global Forwards
struts-config.xml
<!-- ====================== Global Forward Definitions -->
<global-forwards>
<forward name="showStudents" path="/showStudents.do"/>
</global-forwards>
menu.jsp
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
40
<b>Data Entry Menu</b>
<ul>
<li><html:link forward="showStudents">Students</html:link></li>
...
</ul>
21
Message Resources
MessageResources.properties
# -- app --
app.title=Struts Data Entry Application
...
students.jsp
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<html>
41
<head>
<title><bean:message key="app.title" /></title>
</head>
...
</html>