Vous êtes sur la page 1sur 43

Tcnicas de Programao II

Prof. MSc. Gustavo Rodrigues


profgustavo@fiap.com.br

Parte 09
(MVC)

Agenda
 Modelo MVC
Entendendo os benefcios do MVC
Usando RequestDispatcher para implementar MVC
Passando requests dos servlets para as pginas JSP
Escolhendo entre as diferentes opes de apresentao dos dados
Comparando estratgias de compartilhamento de dados

Possibilidades para tratar uma requisio


 Somente Servlet. Funciona bem quando:
Sada um tipo binrio. Ex.: uma imagem
No h sada. Ex.: voc est fazendo um fowarding ou
redirecionamento
Layout da pgina extremamente varivel. Ex.: portal

 Somente JSP. Funciona bem quando:


Sada principalmente em caracteres. Ex.: HTML
Layout da pgina quase todo fixo

 Combinao (Arquitetura MVC). Necessria quando:


Uma nica requisio ir resultar em mltiplos resultados
substancialmente diferentes
Voc tem um time de desenvolvimento grande com diferentes
membros fazendo desenvolvimento web e lgica de negcio
Voc faz processamento de dados complexo, mas tem um layout
relativamento fixo
4

Fluxo de Controle MVC

HTML or JSP
Java Code
(Business Logic)
Results
(beans)

submit form

Form

(URL matches urlpattern of servlet)

Servlet

(Store beans in
request, session, or
application scope)

JSP1
JSP2
JSP3

(Extract data from beans


and put in output)

Desentendimentos sobre MVC


 Um framework elaborado necessrio
Frameworks so teis algumas vezes
Struts
JavaServer Faces (JSF)

Mas eles no so necessrios!


Implemtentando MVC com o RequestDispatcher embutido funciona
bem para quase todas as aplicaes, no importa o tamanho

 MVC muda a arquitetura do sistema como um todo


Voc pode usar MVC para requisies individuais
Pense nisso como a abordagem MVC, no a arquitetura MVC

Implementando MVC com RequestDispatcher


1.
2.

Defina os beans para representar os dados


Use um servlet para tratar requisies

3.

Popule os beans

4.

O servlet l os parmetros da requisio, valida os dados de


entrada etc.
O servlet chama a lgica de negcio (cdigo especfico da
aplicao) ou cdigo de acesso a dados para obter os
resultados. Resultados so colocados nos beans que foram
definidos no passo 1.

Armazene o bean no request, session, ou servlet context

O servlet chama setAttribute no objeto do request, session, ou


servlet context para guardar uma referncia para os beans que
representam os resultados do request

Implementando MVC com RequestDispatcher


5.

Passe a requisio para uma pgina JSP

6.

O servlet determina qual pgina JSP apropriada para a


situao e usa o mtodo forward do RequestDispatcher para
transferir o controle para esta pgina

Extraia os dados dos beans

A pgina JSP acessa os beans com jsp:useBean and um escopo


que bata com a localizao do passo 4. A pgina ento usa
jsp:getProperty para dar a sada das propriedades do bean.
A pgina JSP no cria ou modifica o bean; ela simplesmente
extrai e mostra os dados que o servlet criou.

Exemplo Request Forwarding


public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
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);
}
9

jsp:useBean no MVC vs. apenas em pginas JSP


 A pgina JSP no deve criar os objetos
O servlet, no a pgina JSP, deve criar todos os objetos de dados.
Assim, para garantir que a pgina JSP no ir criar objetos, voc
deve usar:
<jsp:useBean ... type="package.Class" />

no lugar de:
<jsp:useBean ... class="package.Class" />

 A pgina JSP no deve modificar os objetos


Ento, voc deve usar jsp:getProperty mas no jsp:setProperty

10

Lembrando: jsp:useBean - Alternativas de Escopo


 request
<jsp:useBean id="..." type="..." scope="request" />

 session
<jsp:useBean id="..." type="..." scope="session" />

 application
<jsp:useBean id="..." type="..." scope="application" />

 page
<jsp:useBean id="..." type="..." scope="page" />
ou apenas
<jsp:useBean id="..." type="..." />
Este escopo no usado na arquitetura MVC
11

Compartilhamento com Request

 Servlet
ValueObject value = new ValueObject(...);
request.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher
("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);

 Tag XML
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="request" />
<jsp:getProperty name="key" property="someProperty" />

 Expression Language
${key.someProperty}

12

Compartilhamento com Session

 Servlet
ValueObject value = new ValueObject(...);
HttpSession session = request.getSession();
session.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher
("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);

 Tag XML
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="session" />
<jsp:getProperty name="key" property="someProperty" />

 Expression Language
${key.someProperty}
13

Compartilhamento com Servlet-Context

 Servlet
synchronized(this) {
ValueObject value = new ValueObject(...);
getServletContext().setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher
("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
}

 Tag XML
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="application" />
<jsp:getProperty name="key" property="someProperty" />

 Expression Language
${key.someProperty}
14

URL relativas nas pginas JSP


 Questo
Forwarding com um request dispatcher transparente para o
cliente. A URL original a nica URL que o browser conhece.

 Por que isso importa?


O que o browser ir fazer com as seguintes tags:
<IMG SRC="foo.gif" >
<LINK REL=STYLESHEET
HREF="JSP-Styles.css"
TYPE="text/css">
<A HREF="bar.jsp"></A>
Resposta: o browser os trata como relativo a URL do servlet

 Soluo mais simples:


Use URLs que comeam com uma barra /
15

Aplicando MVC: Saldo de Conta Bancria


 Bean
BankCustomer

 Servlet que popula bean e passa para pgina JSP


apropriada
L cdigo do cliente, chama cdigo de acesso a dados para popular
o bean BankCustomer
Usa saldo atual para decidir qual pgina apropriada para mostrar

 Pginas JSP para mostrar o resultado

Saldo negativo: Pgina de aviso


Saldo normal: Pgina padro
Saldo alto: pgina com anncios includos
Cdigo de cliente desconhecido: Pgina de erro
16

Saldo de Conta Bancria - servlet


public class ShowBalance extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
BankCustomer customer = DAO.getCustomer
(request.getParameter("id"));
String address;
if (customer == null) {
address =
"/WEB-INF/bank-account/UnknownCustomer.jsp";
} else if (customer.getBalance() < 0) {
address =
"/WEB-INF/bank-account/NegativeBalance.jsp";
request.setAttribute("badCustomer", customer);
}

RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
17

Saldo de Conta Bancria Tag XML (saldo neg.)

<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="badCustomer"
type="coreservlets.BankCustomer"
scope="request" />
Watch out,
<jsp:getProperty name="badCustomer"
property="firstName" />,
we know where you live.
<P>
Pay us the $<jsp:getProperty name="badCustomer"
property="balanceNoSign" />
you owe us before it is too late!
</BODY></HTML>

18

Saldo de Conta Bancria EL (saldo neg.)

<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,
${badCustomer.firstName},
we know where you live.
<P>
Pay us the $${badCustomer.balanceNoSign}
you owe us before it is too late!
</BODY></HTML>

19

Saldo de Conta Bancria resultados

20

Compartilhamento de dados: Request


 Objetivo
Mostrar um nmero aleatrio para o usurio
 Tipos de compartilhamento
Cada requisio deve resultar em um novo nmero, assim
compartilhamento request apropriado

21

Compartilhamento Request - bean


package coreservlets;
public class NumberBean {
private double num;
public NumberBean() {
num = 0;
}
public double getNumber() {
return(num);
}
public void setNumber(double number) {
num = number;
}
}
22

Compartilhamento Request - servlet


public class RandomNumberServlet extends
HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
NumberBean bean = new NumberBean();
bean.setNumber(Math.random());
request.setAttribute("randomNum", bean);
String address = /RandomNum.jsp";
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
}
}

23

Compartilhamento Request JSP Tag XML

<BODY>
<jsp:useBean id="randomNum"
type="coreservlets.NumberBean"
scope="request" />
<H2>Random Number:
<jsp:getProperty name="randomNum"
property="number" />
</H2>
</BODY></HTML>

24

Compartilhamento Request JSP EL

<BODY>
<H2>Random Number:
${randomNum.number}
</H2>
</BODY></HTML>

25

Compartilhamento Request Resultado

26

Compartilhamento de dados: Session


 Objetivo
Mostrar nome e sobrenome do usurio
Se o usurio no tiver informado seu nome, queremos usar
qualquer nome que ele tenha dado anteriormente
Se o usurio no informar o nome, nem tiver dado o nome em
nenhum momento anterior, um aviso deve ser dado

 Tipo de compartilhamento
Dado armazenado para cada cliente, ento compartilhamento
de sesso apropriado

27

Compartilhamento Session - bean


public class NameBean {
private String firstName = "Missing first name";
private String lastName = "Missing last name";
public NameBean() {
firstName = "Missing first name";
lastName = "Missing last name";
}
public String getFirstName() {
return(firstName);
}
public void setFirstName(String firstName) {
if (!isMissing(firstName)) {
this.firstName = firstName;
}
}
... // getLastName, setLastName
private boolean isMissing(String value) {
return((value == null) || (value.trim().equals("")));
}
}

28

Compartilhamento Session - servlet


public class RegistrationServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
NameBean nameBean =
(NameBean)session.getAttribute("nameBean");
if (nameBean == null) {
String firstName = request.getParameter("firstName");
String lastName = request.getParameter("lastName");
nameBean = new NameBean();
nameBean.setFirstName(firstName);
nameBean.setLastName(lastName);
session.setAttribute("nameBean", nameBean);
}
String address = "/ShowName.jsp";
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
}
}

29

Compartilhamento Session JSP Tag XML

<BODY>
<H1>Thanks for Registering</H1>
<jsp:useBean id="nameBean"
type="coreservlets.NameBean"
scope="session" />
<H2>First Name:
<jsp:getProperty name="nameBean"
property="firstName" /></H2>
<H2>Last Name:
<jsp:getProperty name="nameBean"
property="lastName" /></H2>
</BODY></HTML>

30

Compartilhamento Session JSP EL

<BODY>
<H1>Thanks for Registering</H1>
<H2>First Name:
${nameBean.firstName}</H2>
<H2>Last Name:
${nameBean.lastName}</H2>
</BODY></HTML>

31

Compartilhamento Session Resultado

32

Compartilhamento de dados: ServletContext


 Objetivo
Mostar um nmero primo de um tamanho especfico
Se o usurio no informar o tamanho desejado, ns queremos
usar qualquer nmero primo que tenha sido computado mais
recentemente por qualquer usurio

 Tipo de compartilhamento
Dado compartilhado entre mltiplos clientes, ento
compartilhamento baseado na aplicao apropriado

33

Compartilhamento ServletContext - bean


package coreservlets;
import java.math.BigInteger;
public class PrimeBean {
private BigInteger prime;
public PrimeBean(String lengthString) {
int length = 150;
try {
length = Integer.parseInt(lengthString);
} catch(NumberFormatException nfe) {}
setPrime(Primes.nextPrime(Primes.random(length)));
}
public BigInteger getPrime() {
return(prime);
}

}
34

Compartilhamento ServletContext - servlet


public class PrimeServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
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/mvc-sharing/ShowPrime.jsp";
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
}
}
}

35

Compartilhamento ServletContext JSP Tag XML

<BODY>
<H1>A Prime Number</H1>
<jsp:useBean id="primeBean"
type="coreservlets.PrimeBean"
scope="application" />
<jsp:getProperty name="primeBean"
property="prime" />
</BODY></HTML>

36

Compartilhamento ServletContext JSP EL

<BODY>
<H1>A Prime Number</H1>
${primeBean.prime}
</BODY></HTML>

37

Compartilhamento ServletContext Resultado

38

Forwarding a partir de pginas JSP


<% String destination;
if (Math.random() > 0.5) {
destination = "/examples/page1.jsp";
} else {
destination = "/examples/page2.jsp";
}
%>
<jsp:forward page="<%= destination %>" />

 Possvel, mas m idia


Lgica de negcio e controle pertence aos servlets
Mantenha JSP focado na apresentao dos dados

39

J2EE Design Patterns


 Design pattern
Uma soluo repetvel para um problema de software que ocorre
com frequncia

 Abordagens
Nvel baixo: estrutura de dados
Nvel mdio: algoritmos
Nvel alto: design patterns

40

Model View Controller


 Definio
Uma abordagem onde voc quebra a responsabilidade em trs pedaos
O controller: a parte que trata a requisio, decide qual lgica chamar e
decide qual pgina JSP deve ser utilizada para sada
O model: as classes que representam os dados sendo mostrados
O view: as pginas JSP que representam a sada que os clientes vem.

 Exemplos
MVC usando RequestDispatcher
Struts
JSF

41

Front Controller
 Definio
Uma extenso da abordagem MVC, onde um simples servlet o
ponto de entrada para a aplicao inteira. O front controller
transfere requisies para todo o resto.

 Exemplos
Aplicao MVC que tem somente um servlet
Struts
JSF

42

Copyright 2009 Prof. Gustavo Rodrigues


Todos direitos reservados. Reproduo ou divulgao total ou parcial deste documento expressamente
proibido sem o consentimento formal, por escrito, do Professor (autor).