Microsoft PowerPoint 14 MVC.pptx
© 2010 Marty Hall
Integrating Servlets and JSP:
The Model View Controller
(MVC) A
rchitecture
Architecture
Originals of Slides and Source Code for Examples:
http://courses.coreservlets.com/Course-Materials/csajsp2.html
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
2
Developed and taught by well-known author and developer. At public venues or onsite at your location.
© 2010 Marty Hall
For live Java EE training, please see training courses
at http://courses.coreservlets.com/.
Servlets, JSP, Struts, JSF 1.x, JSF 2.0, Ajax (with jQuery, Dojo,
Prototype, Ext-JS, Google Closure, etc.), GWT 2.0 (with GXT),
Java 5, Java 6, SOAP-based and RESTful Web Services, Spring,
Hibernate/JPA, and customized combinations of topics.
Taught by the author of Core Servlets and JSP, More
Servlets and JSP and this tutorial
,
. Available at public
Available at public
Customized Java EE Training: http://courses.coreservlets.com/
venues, or customized versions can be held on-site at your
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
organization. Contact hall@coreservlets.com for details.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Agenda
• Understanding the benefits of MVC
• Using RequestDispatcher to implement MVC
• Forwarding requests from servlets to JSP
pages
• Handling relative URLs
• Choosing among different display options
• Comparing data-sharing strategies
4
© 2010 Marty Hall
MVC Motivation
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
5
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Uses of JSP Constructs
Simple
p
• Scripting elements
elements calling
servlet
Application
code directly
• Scripting elements
g
calling servlet
g
code indirectly (by means of utility
classes)
• Beans
• Servlet/JSP combo (MVC)
• MVC i
w th
ith JSP
i
express on language
Complex
Application • Custom tags
• MVC with
ith b
t
eans, cus
t
om
d
ags, an
a framework like Struts or JSF
6
Why Combine Servlets & JSP?
• Typical picture: use JSP to make it easier to
devel
d
op an
i
ma ntain the HTM
HTML content
– For simple dynamic code, call servlet code from
scripting e
lements
elements
– For slightly more complex applications, use custom
classes called from scripting elements
– For moderately complex applications,
use beans and custom tags
• But, that
that’s not
enough
– For complex processing, starting with JSP is awkward
– Despite the ease of separating the real code into separate
classes, beans, and custom tags, the assumption behind
JSP is that a single page gives a single basic look
7
Possibilities for Handling a
Single R
equest
Request
• Servlet only. Works well when:
– O
i
utput s a bi
binary ty
E
pe. .g.: an image
– There is no output. E.g.: you are doing forwarding or redirection as
in Search Engine example.
– Format/layout of page is highly variable. E.g.: portal.
• JSP only. Works well when:
– Output is mostly character data. E.g.: HTML
– Format/layout mostly fixed.
• Combination (MVC architecture). Needed when:
– A sin l
gle request will result i n multiple substanti
tiall
lly d
iff
different-
looking results.
– You have a large development team with different team members
doing the
W
eb
Web development
a
nd
and the
business
l ogic
logic.
– You perform complicated data processing, but have a relatively
fixed layout.
8
MVC Misconceptions
• An elaborate framework is necessary
– Frameworks are sometimes useful
• Struts
• JavaServer Faces
(
JSF)
(JSF)
– They are not required!
• Implementing MVC with the builtin RequestDispatcher
works v
ery
very well
well f or
for most simple
and
moderately
c
omplex
complex
applications
• MVC totally changes your overall system
design
– You can use MVC for individual requests
– Think of it
it
t
as h
the MVC
MVC
h
approac , not t h
the
MVC architecture
9
• Also called the Model 2 approach
© 2010 Marty Hall
Beans
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
10
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Review: Beans
• Java classes that follow certain conventions
– Must have a zero-argument (empty) constructor
• You can satisfy this requirement either by explicitly
defining such a constructor
g
or by omitting all constructors
g
• In this version of MVC, it is not required to have zero arg
constructor if you only instantiate from Java code
– Should h
ave
have n
o
no public
instance
variables
(fields)
• I hope you already follow this practice and use accessor
methods instead of allowing direct access to fields
– Persistent values should be
be accessed t hrough
through methods
called getXxx and setXxx
• If class has method getTitle that returns a String, class
i
i
s sa d
id t h
o ave a St
St irng p
t
roperty named i
t
l
t e
• Boolean properties can use isXxx instead of getXxx
11
Bean Properties: Examples
Method Names
Property Name
Example JSP Usage
getFirstName
firstName
<jsp:getProperty … property="firstName"/>
setFirstName
<jsp:setProperty … property="firstName"/>
${customer.firstName}
isExecutive
executive
<jsp:getProperty … property="executive"/>
setExecutive
<jsp:setProperty … property="executive"/>
(boolean property)
${customer.executive}
getExecutive
executive
<jsp:getProperty … property="executive"/>
setExecutive
<jsp:setProperty … property="executive"/>
(boolean property)
${customer.executive}
getZIP
ZIP
<jsp:getProperty … property="ZIP"/>
setZIP
<jsp:setProperty … property="ZIP"/>
${address.ZIP}
Note 1: property name does not exist anywhere in your code. It is just a shortcut for the method name.
Note 2: property name is derived only from method name. Instance variable name is irrelevant.
12
Example: StringBean
package coreservlets;
public class StringBean {
private String message = "No message specified";
public String getMessage() {
return(message);
}
public void setMessage(String message) {
this.message = message;
}
}
• Beans installed in normal Java directory
– Eclipse: src/folderMatchingPackage
– Depl
d
oye : …/WEB-INF/ l
c asses/f
/ old
lderMatch
k
ingPac age
• Beans (and utility classes) must always be in packages!
13
© 2010 Marty Hall
Basic MVC Design
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
14
Developed and taught by well-known author and developer. At public venues or onsite at your location.
MVC Flow of Control
HTML or JSP
Java Code
(Business Logic)
R
l
esu ts
(beans)
submit form
Form
Servlet
(Form ACTION matches
(Store beans in request,
url-pattern of servlet)
session, or application scope)
request.setAttribute("customer",
currentCustomer);
JSP1
JSP2
JSP3
(Extract data from beans
and put in
p
output
p )
${customer.firstName}
15
Implementing MVC with
RequestDispatcher
1. Define beans to represent result data
–
Ordinary Java classes with at least one getBlah method
2. Use a servlet to handle requests
– Servl
d
et rea
h
s request parameters, c
k
ec
f
s or missing
and malformed data, calls business logic, etc.
3. Obtain bean instances
– The servlet invokes business logic (application-specific
code) or data-access code to obtain the results.
4. Store the bean in the request, session, or
servlet context
– The servl t
e
ll
ca
tAtt
s se
ib
r ute
th
on e request, session, or
servlet context objects to store a reference to the beans
16
that represent the results of the request.
Implementing MVC with
RequestDispatcher (Continued)
5. Forward the request to a JSP page.
– The servlet determines which JSP page is appropriate to
the situation and uses the forward method of
RequestDispatcher to transfer control
to
to that
that page.
page.
6. Extract the data from the beans.
– JSP 1.2: the JSP page accesses beans with js
j p:useBean
and a scope matching the location of step 4. The page
then uses jsp:getProperty to output the bean properties.
– JSP 2
0
. : the
the JSP page
page u
ses
uses
${nameFromServlet.property} to output bean properties
– Either way, the JSP page does not create or modify the
bean; it merely extracts and displays data that the servlet
created.
17
Request Forwarding Example
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
... // Do business logic and get data
String operation = request.getParameter("operation");
if (operation ==
null)
{
operation = "unknown";
}
String address;
if (operation.equals("order")) {
address = "/WEB-INF/Order.jsp";
} else if (operation.equals("cancel")) {
address =
"/WEB-INF/Cancel jsp
.
";
} else {
address = "/WEB-INF/UnknownOperation.jsp";
}
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
18
}
jsp:useBean in MVC vs.
in Standalone
JSP
P
ages
Pages
• The JSP page should not create
th
b
e o j
bjects
– The servlet, not the JSP page, should create all the data
objects. So
So, to
to guarantee t hat
that the
the JSP page
page w
ill
will not create
objects, you should use
<jsp:useBean ... type="package.Class" />
i
d
nstea of
<jsp:useBean ... class="package.Class" />
• The JSP page should not modify
the objects
– So, you should
ld
j
use sp:getProperty but not
jsp:setProperty.
19
© 2010 Marty Hall
Scopes:
request, session, and
application (
ServletContext)
(ServletContext)
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
20
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Reminder: jsp:useBean
Scope Alternatives
(JSP 1
2
. Only!)
• request
– <jsp:useBean id="..." type="..." scope="request" />
• session
– j
<
B
sp:use
i
ean d
id "
=
"
...
"
type=
"
...
"
scope= session" />
• application
– <jsp:useBean id=
"
id=
"
... type="
type=
"
... scope="application
a
"
pplication />
• page
– <jsp:useBean id
=" "
... type="
type
"
... scope="
scope page"
page />
or just
<jsp:useBean id="..." type="..." />
– Thi
i
s scope s not used i n MVC
MVC (Model 2) architecture
21
Request-Based Data Sharing
• Servlet
ValueObject value = LookupService.findResult(...);
request.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher
("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
• JSP 1.2
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="request" />
<jsp:getProperty name="key" property="someProperty" />
JSP 2 0
Name chosen by the servlet
• JSP 2.0
Name chosen by the
.
Name of accessor method, minus the
word "get", with next letter changed
to lower case.
${key.someProperty}
22
Request-Based Data Sharing:
Simplified E
xample
Example
• Servlet
Assume that the Customer constructor
handles missing/malformed data.
Customer myCustomer =
Lookup.findCust(request.getParameter("customerID"));
request.setAttribute("customer", myCustomer);
RequestDispatcher dispatcher =
request.getRequestDispatcher
("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
• JSP 1.2
<jsp:useBean id="customer" type="somePackage.Customer"
scope="request" />
<jsp:getProperty name="customer" property="firstName"/>
• JSP 2
0
.
Note: the Customer class must
${customer.firstName}
have a method called “getFirstName”.
23
Session-Based Data Sharing
• Servlet
ValueObj
bject value = LookupService.fi
findResult(...);
HttpSession session = request.getSession();
session.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher
("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
• JSP 1.2
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="session" />
<jsp:getProperty name="key" property="someProperty" />
• JSP 2
0
.
${key.someProperty}
24
Session-Based Data Sharing:
Variation
• Redirect to page instead of forwarding to it
– U
d
se response.sen R
dR d
e i
di
i
rect nstead of RequestDi
Dispatcher.f
d
orwar
• Distinctions: with sendRedirect:
– User sees JSP URL (user sees
(
only servlet URL with
RequestDispatcher.forward)
– Two round trips to client (only one with forward)
• Advantage of sendRedirect
– User can visit JSP page separately
• User can bookmark JSP page
• Disadvantages of
of sendRedirect
– Two round trips to server is more expensive
– Since user can visit JSP page without going through servlet first,
b
d
ean
i
ata m h
ight not be avail
ilabl
ble
• So, JSP page needs code to detect this situation
25
ServletContext-Based Data
Sharing (
Rare)
(Rare)
• Servlet
synchronized(this) {
ValueObject value = SomeLookup.findResult(...);
getServletContext().setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher
("/WEB-INF/SomePage.jsp");
dispatcher forward
.
(request
response);
,
}
• JSP 1.2
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="application" />
<jsp:getProperty name="key" property="someProperty" />
• JSP 2.0
${key.someProperty}
26
Relative URLs in JSP Pages
• Issue:
– Forwarding with a request dispatcher is transparent to the
client. Original URL is only URL browser knows about.
• Why does this
this matter?
matter?
– What will browser do with tags like the following?
<img src="foo.gif" …>
<link rel="stylesheet"
href="
href my-styles.css"
type="text/css">
<a href="bar.jsp">…</a>
– Browser treats addresses as relative to servlet URL
27
© 2010 Marty Hall
Examples
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
28
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Applying MVC:
Bank Account
Balances
• Bean
– B k
an C
kCustomer
• Business Logic
– BankCustomerLookup
• Servlet that populates bean and forwards to
appropriate JSP page
– Reads c
ustomer
customer I
D
ID, calls
calls BankCustomerLookup
’
BankCustomerLookup s
data-access code to obtain BankCustomer
– Uses current balance to decide on appropriate result page
• JSP p
ages
pages to display results
– Negative balance: warning page
– Regular balance: standard page
– Hi h
g b
alance: page with adverti
tisements added
– Unknown customer ID: error page
29
Bank Account Balances:
Servlet Code
Code
public class ShowBalance extends HttpServlet {
public void doGet
p
(Htt
(
pServletRe
p
quest
q
request
q
,
HttpServletResponse response)
throws ServletException, IOException {
BankCustomer currentCustomer =
BankCustomerLookup
BankCustomerLookup getCustomer
.
(request.getParameter("id"));
request.setAttribute("customer", currentCustomer);
String address;
if (currentCustomer == null) {
address =
"/WEB-INF/bank-account/UnknownCustomer.jsp";
} e
lse
else i
f
if (
currentCustomer
(
getBalance
.
()
() <
0
)
0) {
address =
"/WEB-INF/bank-account/NegativeBalance.jsp";
} ...
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
30
Bank Account Balances:
Bean
public class BankCustomer {
private final String id, firstName, lastName;
private final double balance;
Since the constructor is called from Java only
(never from JSP), the requirement for a zero-arg
constructor is eliminated. Also, since bean state
is set only with constructor, rather than with
public BankCustomer(String id,
jsp:setProperty, we can eliminate setter
String firstName
methods and make the class immutable.
String firstName,
String lastName,
double balance) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.balance = balance;
}
// Getters for four instance variables. No setters.
public double getBalanceNoSign() {
return(Math.abs(balance));
}
31
}
Bank Account Balances:
Business Logic
public class BankCustomerLookup {
private static
M
ap<
Map<String,BankCustomer>
String,BankCustomer
c
ustomers;
customers;
static {
// Populate Ma
p
p with some sam
p
ple customers
p
}
…
public static BankCustomer getCustomer(String id) {
return(customers.get(id));
}
}
32
Bank Account Balances:
Input Form
…
<fieldset>
<legend>Bank Account Balance</legend>
<form action="./show-balance">
Customer ID: <input t
p
yp
y e="text" name="id"><br
p
>
<input type="submit" value="Show Balance">
</form>
</fieldset>
For the servlet, use the address http://host/appName/show-balance that is set via url-pattern in web.xml
…
33
Bank Account Balances:
JSP 1
2
. C
ode
Code (Negative
Balance)
Balance)
…
<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
<TR><TH CLASS="TITLE">
We Know Where You Live!</TABLE>
<P>
<IMG SRC="/bank-support/Club.gif" ALIGN="LEFT">
<jsp:useBean id="customer"
type="coreservlets.BankCustomer"
scope="request" />
Watch out,
<jsp:getProperty name="customer"
property="firstName" />,
we know where you live.
<P>
Pay us the $<jsp:getProperty name="customer"
property="balanceNoSign" />
you owe us before it is too late!
</BODY></HTML>
34
Bank Account Balances:
JSP 2
0
. C
ode
Code (Negative
Balance)
Balance)
…
<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
<TR><TH CLASS="TITLE">
We Know Where You Live!</TABLE>
<P>
<IMG SRC="/bank-support/Club.gif" ALIGN="LEFT">
Watch out, ${customer.firstName},
we know where you live.
<P>
Pay us the $${customer.balanceNoSign}
you owe us before it
it is too l t
a
!
e
</BODY></HTML>
35
Bank Account Balances:
web.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<web-
<web app version
="
version
2 4
. "
4
>
...
<!-- Use the URL http://host/app/show-balance instead of
http://host/app/servlet/coreservlets.ShowBalance -->
<servlet>
<servlet-name>ShowBalance</servlet-name>
<servlet-class>coreservlets.ShowBalance</servlet-class>
</servlet>
<servl
i
et-mapp ng>
<servlet-name>ShowBalance</servlet-name>
<url-pattern>/show-balance</url-pattern>
</servlet
</
-
servlet mapping>
-
...
</web-app>
36
Bank Account Balances:
Results
37
Comparing Data-Sharing
Approaches: Request
• Goal
– Display a random number to the user
• Type of sharing
– Each request should result in a new number, so request-
based sharing is app
ppropriate.
38
Request-Based Sharing: Bean
package coreservlets;
public class NumberBean {
private final double num;
public NumberBean(double number) {
this.num = number;
}
public double getNumber() {
return(num);
);
}
}
The property
The property name in
name in JSP will be
will be “number”. The property
. The propert name is
y name derived from the method
is derived
name,
from the method
not from
name,
the instance variable name. Also note the lack of a corresponding setter.
39
Request-Based Sharing: Servlet
public class RandomNumberServlet extends HttpServlet {
public void
doGet
(
doGet HttpServletRequest
(
request,
HttpServletResponse response)
throws ServletException, IOException {
NumberBean bean =
RanUtils.getRandomNum(request.getParameter("range"));
request.setAttribute("randomNum", bean);
String address = "
g
/WEB-INF
/
/mvc-sharin
/
g/RandomNum.
g/
js
j p"
p ;
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(re
p
quest, res
q
ponse);
p
}
}
40
Request-Based Sharing:
Business Logic
public class RanUtils {
public static
NumberBean
getRandomNum(String
getRandomNum
rangeString)
rangeString
{
double range;
try {
range =
Double.parseDouble
(rangeString
(
);
rangeString
} catch(Exception e) {
range = 10.0;
}
return(new NumberBean(Math.random() * range));
}
}
41
Request-Based Sharing:
URL Pattern
(web xml)
.
...
<servlet>
<servlet-name>RandomNumberServlet</servlet-name>
<servlet-class>
coreservlets RandomNumberServlet
.
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RandomNumberServlet</servlet-name>
<url-pattern>/random-number</url-pattern>
</se
/servlet-mapping>
...
42
Request-Based Sharing:
Input Form
...
<fieldset>
<legend>Random Number</legend>
<form action="./random-number">
Range: <input type=
"text" name="range"><br/>
<input type="submit" value="Show Number">
</form>
</fieldset>
...
43
Request-Based Sharing: JSP 1.2
…
<BODY>
<jsp:useBean id="randomNum"
type="coreservlets.NumberBean"
scope="request" />
<H2>Random Number:
<jsp:getProperty name="randomNum"
property="number" />
</H2>
</BODY></HTML>
44
Request-Based Sharing: JSP 2.0
…
<BODY>
<H2>Random Number: ${randomNum.number}</H2>
</BODY></HTML>
45
Request-Based Sharing:
Results
46
Comparing Data-Sharing
Approaches: Session
• Goal
– Display users’ first and last names.
– If the users fail to tell us their name, we want to use
whatever name
they gave us
previously.
– If the users do not explicitly specify a name and no
previous name is found, a warning should be displayed.
• Type of sharing
– D
i
ata
d
s store f
or each l
c i
li
i
ent, so sess
b
on-
d
ase sh i
ar
i
ng s
appropriate.
47
Session-Based Sharing: Bean
public class NameBean implements Serializable {
private Strin
p
g firstName
g
= "Missing first name";
g
private String lastName = "Missing last name";
public String getFirstName() {
return(firstName
return(
);
firstName
}
public void setFirstName(String firstName) {
if (!
isMissing
(!
(
isMissing firstName
(
))
firstName
{
this.firstName = firstName;
}
}
... // getLastName, setLastName
private boolean isMissing(String value) {
return((value == null) || (value.trim().equals("")));
}
}
48
Session-Based Sharing: Servlet
public class RegistrationServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
synchronized(session) {
NameBean nameBean =
(NameBean)session.getAttribute("name");
if (nameBean == null) {
nameBean = new NameBean();
session.setAttribute("name", nameBean);
}
nameBean.setFirstName(request.getParameter("firstName"));
nameBean.setLastName(request.getParameter("lastName"));
String address = "/WEB-INF/mvc-sharing/ShowName.jsp";
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
}
}
}
49
Session-Based Sharing: JSP 1.2
…
<BODY>
<H1>Thanks for Registering</H1>
<jsp:useBean id="name"
type="coreservlets NameBean
.
"
scope="session" />
<H2>First Name:
<jsp:getProperty name="name"
property="firstName" /></H2>
<H2>Last Name:
<jsp:getProperty name="name"
property="lastName" /></H2>
</BODY></HTML>
50
Session-Based Sharing: JSP 2.0
…
<BODY>
<H1>Thanks for Registering</H1>
<H2>First Name: ${name.firstName}</H2>
<H2>Last Name: ${name.lastName}</H2>
</BODY></HTML>
51
Session-Based Sharing:
Results
Note: url-pattern
in web.xml is
"register".
52
Comparing Data-Sharing
Approaches: ServletContext
• Goal
– Display a prime number of a specified length.
– If the user fails to tell us the desired length, we want to
use w
hatever
whatever p
rime
prime number w
e
we m
ost
most recently
computed
for any user.
• Type of sharing
– Data is shared among multiple clients, so application-
based s
haring
sharing is
appropriate.
53
ServletContext-Based Sharing:
Bean
package coreservlets;
import
p
java.math.Bi
j
gInte
g
ger
g
;
public class PrimeBean {
private BigInteger prime;
public PrimeBean(String lengthString) {
int length = 150;
tr
t y
y {
length = Integer.parseInt(lengthString);
} catch(NumberFormatException nfe) {}
this.prime = Primes.nextPrime(Primes.random(length));
}
public BigInteger getPrime() {
return(prime);
}
…
}
54
ServletContext-Based Sharing:
Servlet
public class PrimeServlet extends HttpServlet {
public void doGet(Htt
p
pServletRe
p
quest re
q
quest,
q
HttpServletResponse response)
throws ServletException, IOException {
String length = request.getParameter("primeLength");
ServletContext context
=
getServletContext();
synchronized(this) {
if ((context.getAttribute("primeBean") == null) ||
(length != null)) {
PrimeBean primeBean
=
new
PrimeBean(length);
context.setAttribute("primeBean", primeBean);
}
String address =
"/
/
WEB-INF
h
mvc-s
i
ar
/
ng Sh
/Sh
i
owPr
j
me.
"
sp ;
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
}
}
}
55
ServletContext-Based Sharing:
JSP 1
2
.
…
<BODY>
<H1>A Prime Number</H1>
<jsp:useBean id="primeBean"
type="coreservlets PrimeBean
.
"
scope="application" />
<jsp:getProperty name="primeBean"
property="prime" />
</BODY></HTML>
56
ServletContext-Based Sharing:
JSP 2
0
.
…
<BODY>
<H1>A Prime Number</H1>
${primeBean.prime}
</BODY></HTML>
57
ServletContext-Based Sharing:
Results
Note: url-pattern in web.xml is "prime".
58
© 2010 Marty Hall
Forwarding a
nd
and
Including
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
59
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Forwarding from JSP Pages
<% String destination;
if (Math random(
.
)
random() > 0.5)
5) {
destination = "/examples/page1.jsp";
} else {
destination =
"/examples/page2 jsp
.
";
}
%>
<jsp:forward page="<%= destination %>
" />
• Legal, but bad idea
idea
– Business and control logic belongs in servlets
– Keep JSP focused on presentation
60
Including Pages Instead of
Forwarding t
o
to Them
• With the forward method of
RequestDispatcher:
– New page generates all of the output
– Original page cannot generate any output
• With the include method of
RequestDispatcher:
– Output
b
can
t
e genera d
e b
y multiple pages
– Original page can generate output before and after the
included page
– Original servlet does not see the output of the included
page (for this, see later topic on servlet/JSP filters)
– Applications
• Portal-like applications (see first example)
• Setting content type for output (see second example)
61
Using RequestDispatcher.include:
portals
response.setContentType("text/html");
String firstTable, secondTable, thirdTable;
if
if (
d
someCon i
di i
t
)
on
{
firstTable = "/WEB-INF/Sports-Scores.jsp";
secondTable = "/WEB-INF/Stock-Prices.jsp";
thirdTable = "/WEB-INF/Weather.jsp";
} else
if
(
)
...
{
}
...
RequestDispatcher dispatcher =
request.getRequestDispatcher("/WEB-INF/Header.jsp");
dispatcher.include(request, response);
dispatcher =
request.getRequestDispatcher(firstTable);
dispatcher.include(request, response);
dispatcher =
request.getRequestDispatcher(secondTable);
dispatcher.include(request, response);
dispatcher =
request.getRequestDispatcher(thirdTable);
dispatcher.include(re
p
quest, response);
dispatcher =
request.getRequestDispatcher("/WEB-INF/Footer.jsp");
dispatcher.include(request, response);
62
Using RequestDispatcher.include:
Setting Content
-Type of
Output
// From Ajax example
public void doGet
(
doGet
)
... ... {
...
if ("xml".equals(format)) {
response.setContentT
p
yp
y e
p ("text/xml"
(
);
)
outputPage = "/WEB-INF/results/cities-xml.jsp";
} else if ("json".equals(format)) {
response.setContentType("application/json");
outputPage = "/WEB-INF/results/cities-json.jsp";
} else {
response.setContentType("text/plain");
t
ou
t
pu P
tPage = "/WEB
INF/
-
l
resu t
lt /
s
i
c ti
iti
t
es-s
i
r
j
ng.
"
sp ;
}
RequestDispatcher dispatcher =
request getRequestDispatcher
.
(outputPage
(
);
outputPage
dispatcher.include(request, response);
}
63
cities-xml.jsp
<?xml version="1.0" encoding="UTF-8"?>
<cities>
<city>
<name>${cities[0].name}</name>
<time>${cities[0].shortTime}</time>
<population>${cities[0].population}</population>
</city>
...
</cities>
• Notes
– Because I use .jsp (not .jspx) and classic JSP syntax, the
default content-type is text/html
– I c
ould
could u
se
use <%@
page
page contentType
="
contentType text/xml"
text/xml %> here
,
but it is more convenient to do it in calling servlet and
keep this page simple and focused on presentation
64
Summary
• Use MVC (Model 2) approach when:
– One submission will
l
resu t i
h
n more t
b
an one asic look
– Several pages have substantial common processing
• Architecture
– A servlet answers the original request
– Servlet does the real work & stores results in beans
• Beans stored in HttpServletRequest, HttpSession, or
ServletContext
– Servlet forwards to JSP page via forward method of
RequestDispatcher
– JSP page reads data from beans
• JSP 1
2:
. jsp:useBean with appropriate
scope (request
,
session, or application) plus jsp:getProperty
• JSP 2.x: ${beanName.propertyName}
65
© 2010 Marty Hall
Questions?
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Struts, Ajax, GWT 2.0, Spring, Hibernate, SOAP & REST Web Services, Java 6.
66
Developed and taught by well-known author and developer. At public venues or onsite at your location.