Oracle Certified Professional, Java EE 5 Web Component ... · Capítulo 1 - Introdução a...
Transcript of Oracle Certified Professional, Java EE 5 Web Component ... · Capítulo 1 - Introdução a...
Oracle Certified Professional,
Java EE 5 Web Component
Developer
Resumo do livro Heard First - Servlets
e JSP (5º edição)
Erick Ferreira Macedo
Capítulo 1 - Introdução a Arquitetura.
HTTP (HyperText Transfer Protocol) é o protocolo que os cliente e os Servidores usam para se
comunicarem.O HTTP roda no topo do TCP/IP com caracteristica especificas para Web
HTML - Informa o Browser como exibir o conteúdo
<img> - Quando o browser encontra uma tag de imagem, ele gera outra solicitação http para ir buscar o
recurso especificado.
Métodos HTTP
GET : seu objetivo é conseguir alguma coisa no servidor.A "?" separa o caminho dos parâmetros. Os
parâmetros são separados usando "&"
- O total de caracteres é realmente limitado (dependendo do servidor)
- Os dados ficará expostos.
- O GET permite armazenar um pagina de formulário aos favoritos, ao contrário do POST.
Solicitação GET : O caminho até o recurso e quaisquer parâmetros adicionados a URL estão incluídos na
linha de solicitação.(figura pagina 15.)
POST : Com o POST, você pode solicitar algo e, ao mesmo tempo enviar dados.
- São designados para solicitações mais complexa, como adicionar dados do formulário em um banco de
dados.
- Os parâmetros enviados via Post não ficam limitados da maneira que ficariam quando se usa um GET.
Solicitação POST : Os parâmetros são enviados no corpo da mensagem "payload".(figura pagina 16.)
Resposta HTTP : Uma resposta HTTP é composta de header e corpo. A informação do header informa o
browser o protocolo que está sendo usado, se a solicitação obteve êxito, e que tipo de conteúdo está
incluso no corpo (MIME Type ou Content-Type). O corpo possui o conteúdo (HTML).(figura pagina 17)
URL (Uniform Resource Locators ou Localizadores Uniforme de recusos) : Todo recurso na web tem seu
próprio e único endereço nesta padrão. Ele começa com um protocolo, seguido pelo nome do servidor,
um número de porta opcional e geralmente um caminho específico acompanhado do nome do recurso.
Ex:(Protocolo de Comunicação) + (Nome único do servidor Fisico) + (Porta : Opcional o padrão é 80) +
(caminho do recurso) + (nome do conteúdo).
Os números das portas TCP é de 0 1023 são reservadas.
Capítulo 2 - Arquitetura da aplicação Web
CGI - Common Gateway Interface (Interface de passagem comum) - Geralmente é escrito em Perl.
Funcionamento : O servidor recebe uma solicitação e "vê" que a solicitação é para um programa
assistente (CGI), então o servidor abre e roda o programa em um processo separado. A aplicação do
servidor envia junto os parâmetros do request, a aplicação CGI constrói a nova página e devolve o HTML
ao servidor, para o servidor o HTML da aplicação CGI é um pagina estática, a aplicação assistente e
fechada e o servido envia a resposta ao cliente.
Container : O Container oferece os seguintes benefícios para sua aplicação Web : Suporte para
comunicação (O Container conhece o protocolo entre o servidor e ele mesmo ), Gerenciamento do ciclo
de vida dos servlets, Suporte a multithread, Segurança Declarada e Suporte ao JSP para que você possa
se concentrar na lógica de negocio.
Funcionamento : Ao receber uma solicitação (HTTP request), o container cria dois objetos
HttpServletRequest e HttpServletResponse, encontra o servlet correto baseado na URL do request, cria
ou aloca uma thread para o servlet e passa os objetos ao chamar o metodo service do servlet. O método
service() é responsavel por chamar o doXXX() depedendo do tipo do request, no caso do doGet ele gera
um página dinâmica e a insere no objeto response, a thread termina , o container converte o objeto
HttpServletResponse em uma resposta HTTP e envia de volta para o cliente e apaga os objetos
HttpServletRequest e HttpServletResponse.
OBS: É gerado um processo para rodar um programa CGI no servidor para cada solicitação que chega do
cliente, diferente dos Servlets que é um único processo a JVM e é criados threads para cada solicitação.
Deployment Descriptor DD :Oferece um mecanismo declarado para a customização das suas aplicações
sem tocar no código fonte.Mapear o nome dos servlets aumenta a flexibilidade e a segurança da sua
aplicação.
Benefícios do DD:
-Reduz a necessidade de alteração do código-fonte que já foi testado.
-Permite que você ajuste os recursos da sua aplicação, mesmo que não possua o código fonte.
-Permite que você adapte sua aplicação de acordo com diferentes recursos como banco de dados, sem
ter que recompilar e testar nenhum código
-Facilita a manutenção das informações dinâmicas, tais como segurança, controle de acesso.
-Permite que aqueles que não sejam programadores modifiquem e distribuam suas aplicações
Capítulo 3 - Minitutorial do MVC (Não se aplica neste resumo)
Capítulo 4 - Sendo um Servlet
Servlet : O Servlet possui dois estados :
Inicializado = Após rodar o construtor e init Não existe = Antes de rodar o construtor e init ou após o destroy. Ciclo de Vida : O Container carrega a classe, o construtor roda ,chama o init(passando um ServletConfig)
apenas uma vez durante a vida do servlet e antes de executar o metodo service, chama o service e cada
solicitação roda em uma thread separada, e por fim o destroy para dar o servlet uma chance de limpar
antes de morrer, como o init ele é chamado apenas uma vez.
Você pode sobreescrever o init() da versão padrão, ele é chamado pelo init(ServletConfig) da super
classe,não há uma regra que impeça de sobreescrever o init(ServletConfig) mais se você sobreescrever é
melhor chamar o super init(ServletConfig), você deve sobreescrever pelo menos um método de
serviço(doXXX).As classes do servlet esta em javax.servlet ou javax.servlet.http (exeto aquelas
relacionada a JSPs).
Solicitação
Existe oito métodos no HTTP1.1, Na classe HttpServlet apenas um, o doConnect() não é suportado, os
outros sete tem seu método doXXX() em HttpServlet .
GET:Pede para obter a coisa(recurso/arquivo) na URL requisitada.
POST: Pede para o servidor aceitar informações do corpo anexada na solicitação.
HEAD:Pede apenas parte do header daquilo que o get retorna, é como um GET sem corpo na RESPOSTA
TRACE:Pede um loopback da mensagem de solicitação, para que o cliente veja o que está sendo
recebido do outro lado, para teste de troubleshoot.
PUT :Diz para colocar a informação anexada , o corpo, na URL requisitada.
DELETE:Diz para apagar a coisa(recurso/arquivo) na URL requisitada.
OPTIONS:Solicita uma lista de métodos HTTP.
CONNECT:Diz para conectar em caso de tunneling.
POST: Os paramêtros são enviados no corpo("payload"), e tambem são separados por "&".
Funcionalidade : O POST é usado para serem processados , mudar alguma coisa no servidor. Desvantagem : Não aceita bookmark(adicionar aos favoritos)
GET os paramêtros são enviados na url depois do "?"
Funcionalidade : O GET é usado para obter coisas, nada mais.
Desvantagem : Segurança, Tamanho dos dados que possam ser enviados
Idempotente significa que você pode fazer a mesma coisa repetidamente, sem os indesejáveis efeitos
colaterais, ou seja a mesma solicitação pode ser feitas duas vezes, sem nenhuma conseguência negativa
para o servidor.Segundo a especificação HTTP 1.1 o GET, PUT, HEAD são idempotente, o POST não é
idepotente.Tenha sempre em mente a diferença entre o método HTTP GET e o doGet() do servlet,
apesar da especificação HTTP garantir que o HTTP GET é idempotente, não existe nada que possa
impedi-lo de implementar um metodo doGet não idempotente no seu servlet.
Método HTTP padrão em um action de um form HTML é o GET, se você não tiver um método
correspondente no servlet é gerado um ERRO.
Métodos da solicitação, ServletRequest e HttpServletRequest.
getHeader("nomeHeader") : retorna um string com o valor do Header
getIntHeader("nomeHeader") : converte o retorno em um inteiro, é usado quando você tem certeza
que o retorno é um número.
getRemotePort() : Usado para obter a porta do cliente. O cliente é remoto na visão do servidor.
getServerPort() : Usado para obter a porta para qual a solicitação foi inicialmente enviada.
getLocalPort() : Usada para obter a porta para qual a solicitação foi parar, pois o servidor encontra uma
porta para cada thread.
Resposta
Métodos da resposta, ServletResponse e HttpServletResponse.
setHeader("nome","valor") : Acrescenta um novo valor se o header não existir, caso contrário
sobreescrever o valor.
setIntHeader("nome", 1) : Acrescenta um novo valor "inteiro" se o header não existir, caso contrário
SOBREESCREVE o valor.
addHeader("nome","valor") : Adiciona um novo valor se o header não existir, caso contrário é
adicionado OUTRO valor para o mesmo header.
setContentType("text/html") : conhecido como MIME-TYPE adiciona um header na resposta.
getOutputStream() : retorna um ServletOutputStream é usado para saída com bytes. Usa o WRITE()
para escrever, ex: sos.write(b).
getWrite() : retorna um PrintWriter é usado para saída com caracteres. Usa o PRINTLN() para escrever,
ex: pw.println("texte")
sendRedirect("String") : o browser que faz o trabalho, pois ele retorna um codigo 301 com um header
"Location" contendo a url como valor.Você pode especificar o endereço completo para o sendRedirect
ou usar URLs relativas com "/" (relativo a raiz) ou sem "/" (relativo ao final da url que fez a solicitação).
Se você escrever na resposta e depois usar o sendRedirect é lançado uma IllegalStateException.
Capítulo 5 - Sendo uma Aplicação Web
Parâmetros
Um parâmetro é um objeto não configurado dinamicamente, os parâmetros existe em três objetos da
API do Servlet, são os ServletContext, ServletRequest e ServletConfig.
Parâmetros init: É considerado constantes para o momento da distribuição, não permite configuração.
Não existe nenhum setInitParameter(), e os paramêtros só retorna String.
A expressão "parâmetro init" se refere aos paramêtros init do Servlet por padrão.
ServletConfig : Um objeto por servlet , sua principal função é disponibilizar parâmetros do init e tambem
fornece um getServletContext(). Os parâmetros init do Servlets são lidos apenas uma vez, quando o
container inicia.
No DD , dentro da tag <servlet>
<init-param>
<param-name>adminEmail</param-name>
<param-value>[email protected]</param-value>
</init-param>
SevletContext : Um objeto por aplicação , sua principal função é disponibilizar parâmetros para à
aplicação. Os ServletContext é unico por aplicação(JVM), em um ambiente distribuido com varias JVM
existirão varios ServletContext.
Você obtem o servletContext de duas formas, pelo ServletConfig ou chamar o getServletContext quando
estiver na classe GenericServlet
No DD, fora da tag <servlet>
<context-param>
<param-name>adminEmail</param-name>
<param-value>[email protected]</param-value>
</context-param>
Atributos
Um atributo é um objeto configurado dinamicamente, os atributos existe em três objetos da API do
Servlet, são os ServletContext, ServletRequest e HttpSession.
A diferença de um atributo para um parêmetro é que os atributo podem ser setados dinamicamente e
seu tipo de retorno é objeto, os parametros não podem ser setados dinamicamente e seu tipo de
retorno é String.
Atributos do Contexto não são thread-safe, a solução é sincronizar no próprio objeto do contexto,
porem isto só funciona se todos os outros códigos que manipulam os mesmos atributos do contexto
tambem sincronizarem no ServletContext.
Atributos da Sessão não são thread-safe, a solução é sincronizar no próprio objeto de sessão, o
HttpSession.
Obs: sincronizar o método service é ruim porque detona a capacidade de processamento simultaneo e
não protege contra a concorrencia,pois significa que apenas uma thread de cada vez em uma classe do
servlet pode estar rodando, mais isto não impede que outros servlets ou JSPs de acessarem o atributo.
Apenas os atributos da Solicitação e as variáveis locais são thread-safe.
Importante: Não se esqueça que atributos devem ser convertidos já que o tipo de retorno é um objeto
Listeners
ServletContextListener : É um interface que refere ao ciclo de vida do ServletContext (inicialização e
destruição), basta sua classe implementar a interface e declara no DD:
<Listener>
<listener-class>foo.MyListener</listener-class>
</listener>
OBS: HttpSessionBindingEvent é subclasse de HttpSessionEvent
Interfaces Métodos Eventos
ServletContextListener contextInitialized , contextDestroyed
ServletContextEvent
ServletContextAttributeListener attributeAdded, attributeRemoved, attributeReplaced
ServletContextAttributeEvent
ServletRequestListener requestInitialized , requestDestroyed
ServletRequesEvent
ServletRequestAttributeListener attributeAdded, attributeRemoved, attributeReplaced
ServletRequestAttributeEvent
HttpSessionListener sessionCreated, sessionDestroyed HttpSessionEvent getSession()
HttpSessionAttributeListener attributeAdded, attributeRemoved, attributeReplaced
HttpSessionBindingEvent (getSession(), getName(), getValue())
HttpSessionBindingListener valueBound, valueUnbound HttpSessionBindingEvent (Não existe configuração no DD)
HttpSessionActivationListener sessionDidActivate, sessionWillPassivate
HttpSessionEvent (Não existe configuração no DD)
Importante : O método getValue() que existe nas classes de eventos retorna o valor antigo do
atributo, caso ele seja substituído.
Outros
SingleThreadModel (SMT) é designado a proteger variáveis de instacia. Assegura que os servlets lidem
apenas com uma solicitação de cada vez.Se o Container implementar o SMT com "pool" a semântica do
Servlet muda.
RequestDispatcher : O trabalho é realizado do lado do servidor, ele é usado para encaminha uma
solicitação. O RequestDispatcher possui dois métodos :
forward(ServletRequest req, ServletResponse resp) .
include(ServletRequest req, ServletResponse resp).
Existe duas forma de conseguirmos um RequestDispatcher, através da solicitação e/ou do contexto:
ServletRequest :RequestDispatcher view=request.getRequestDispatcher("pagina.jsp") , o argumento
String pode ser relativo, ou começar com "/" da raiz.
ServletContext :RequestDispatcher view=getServletContext.getRequestDispatcher("/pagina.jsp"), o
argumento String só pode começar com "/" da raiz, senão será lançada uma illegalargumentexception.
Obs: O paramêtro(Caminho do recurso) do método getResourceAsStream do ServletContext deve
começar com "/"
Importante : Você não pode transferir a solicitação se você já submeteu uma resposta, ou seja,
chamou o flush(), isso lança uma IllegalStateException.
Capítulo 6 - Gerenciamento de Sessão
HttpSession : É usado para manter o estado de conversação durante várias solicitações, ou seja, para
uma sessão inteira com o mesmo cliente. O container usa o session ID para se comunicar com o cliente
que envia de volta com cada solicitação subsequente. A uníca coisa que você tem que fazer é informar
ao Container que você quer criar ou usar uma sessão mais é o Container que gera a session ID , criando
um novo objeto cookie, inserindo a session ID dentro do cookie e configurando- o como parte da
resposta. Nas solicitações subsequentes, o Container recebe a session ID de um cookie da solicitação,
compara-a com uma sessão existente e associa essa sessão com a solicitação atual.
Podemos obter o HttpSession atraves do HttpServletRequest e dos eventos HttpSessionEvent e
HttpSessionBindingEvent.
Se o cliente não aceitar cookies você não receberá nenhuma exceção, porem o getSession() sempre
retornará uma nova sessão. Um alternativa é a reescrita de URL porem você deve codificar todas as
URLs que você envia na resposta. Por padrão o Container é configurado para usar os cookies primeiro,
com a reescrita de URL apenas em último caso, exceto na primeira vez, porque ele não consegui saber
se o cookie está funcionado.
Na primeira resposta enviada ao cliente ele tenta o cookie e a reescrita de URL. Assim na segunda
solicitação ele terá a session ID anexada à URL, mas se o cliente aceitar cookies ele terá tambem um
cookie session ID. Assim se o cookie respondeu, quer dizer que o cliente aceita cookies, então ele
ignora a reescrita de URL.
Obs: A única maneira de usar a reescrita de URL é se TODAS as páginas que são parte de uma sessão
forem dinâmicas, ou seja HTML estáticos não funcionam.
Obs: A reescrita de URLs é especifica por fabricante, o tomcat usa ";" no final da url.
Métodos referentes ao HttpSession.
request.getSession() : sempre retorna uma sessão : nova ou existente.
request.getSession(true) : sempre retorna uma sessão : nova ou existente.
request.getSession(false) : só retorna uma sessão se ela existir caso contrario ele retorna null.
session.isNew() : retorna verdadeiro se o cliente ainda não respondeu.Se a sessão estiver destruída é
lançada uma IllegalStateException
getCreationTime() : Retorna o momento que a sessão foi criada pela primeira vez.
getLastAccessedTime() : Retorna a última vez que o Container recebeu uma solicitação para uma
determinada sessão, retorna em milisegundos.
getMaxInactiveInterval() : Retorna o tempo máximo em segundos permitido entra as solicitações do
cliente para esta sessão.
setMaxInactiveInterval() : Especifica o tempo máximo em segundos que você quer permitir entre as
solicitações, terá o mesmo efeito do timeout.
invalidate() : Finaliza a sessão, desvincula todos os atributos da sessão.Se a sessão estiver destruída é
lançada uma IllegalStateException
Timeout no DD :
<web-app>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
Importante: O timeout do DD está em minutos no setMaxInactiveInterval está em segundos.
Importante: Se chamar algum método da sessão após ela destruída é lançada uma
IllegalStateException.
Importante: Configura o timeout para -1 a sessão nunca expirará.
Existe três formas de matar uma sessão.
-Por timeout (configuração no DD ou chamar o setMaxInactiveInterval )
-Chamar o invalidade.
-A aplicação cai.
O objeto HttpSession é único em um ambiente clusterizado, ou sejá ele não existe em mais de uma VM,
pois acontece a migração de sessão , e se torna passiva em uma VM e ativa em outra.
Cookie : É uma par de String/Valor usado para trocar informações entre o servidor e o cliente.
Originalmente foi desenvolvido para trabalhar com sessões, porem podemos usar para outras coisas.
Por padrão, um cookie vive enquanto dura a sessão, mas podemos mandar um cookie permanecer
mesmo depois que o browser é fechado.
Funcionamento
Servidor envia um cookie na resposta com um header : Set-Cookie:username=Tomas
Cliente devolve um cookie através da solicitação como um header : Cookie:username=Tomas
Você pode obter headers relacionado ao cookie, mas você não deve, pois tudo está encapsulado em
três classes na API do servlet:
-javax.servlet.http.HttpServletRequest : getCookies(), retorna um Array de cookies.
-javax.servlet.http.HttpServletResponse: addCookies() , adiciona um new Cookie(String,String);
-javax.servlet.http.Cookie : Cookie(String,String) - Construtor
cookie.setMaxAge(30*60) : é definido em SEGUNDOS, configura este valor para -1 faz com que o cookie
desapareça se o browser fechar.
cookie.getMaxAge() : retorna em SEGUNDOS o tempo de vida do cookies.
Capítulo 7 - Sendo um JSP
JSP : é uma pagina dinamica que é transformda em um Servlet completo rodando em sua aplicação.
Quando o Container transforma o JSP em um servlet ele cria uma subclasse de HttpServlet e
implementa a interface HttpJspPage com os métodos jspInit(), jspDestroy e um método de serviço
chamado _jspService(), no inicio do método de serviço é criado uma pilha de declarações de objetos
implícitos e atribuições.
Ciclo de vida JSP
Funcionamento : O container lê o web.xml, mais não faz nada com os JSPs até que ele seja solicitado
pela primeira vez, na primeira solicitação o container tenta traduzir em código java (Erros de sintaxe JSP
são detectados), depois o container tenta compilar o código java para um arquivo .class, o Container
carrega a classe do servlet gerada e faz com que o método jspInit() rode, e objeto se torna um servlet
completo. É criado uma nova thread para tratar a solicitação e o método _jspService() do servlet roda.
Tudo que acontece depois é uma rotina normal do servlet.A tradução e a compilação acontecem uma
única vez.
Obs: Existe um menção na especificação para que os JSPs sejam traduzidos e compilados
antecipadamente, isso depende do fabricante, então não é garantido.
Metodos da interface javax.servlet.jsp.JspPage
jspInit() : Este método é chamado pelo método init() , Você pode sobreescrever.
JspDestroy() : Este método é chamado pelo método destroy() , Você pode sobreescrever.
Metodo da interface javax.servlet.jsp.HttpJspPage que extende a JspPage
_jspService() : Este método é chamado pelo método service , Não pode sobreescrever.
Configurando parâmetros init em JSPs.
<web-app>
<servlet>
<servlet-name>MyJSP</servlet-name>
<jsp-file>/paginaJSP.jsp</jsp-file>
<init-param>
<param-name>adminEmail</param-name>
<param-value>[email protected]</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>MyJSP</servlet-name>
<url-pattern>/paginaJSP.jsp</url-pattern> // Deve ser igual o jsp-file, caso contrário não funciona
</servlet-mapping>
</web-app>
Objetos Implícitos em um JSP
API Objeto Implícito.
JspWriter out(Um JspWriter é um PrintWriter com algumas funções de buffer)
HttpServletRequest request
HttpServletResponse response
HttpSession session
ServletContext application
ServletConfig config
JspException exception(Disponível apenas para paginas de erros definidas)
PageContext pageContext(Encapsula outros objetos implícitos)
Object page
Existe quadro escopos para atributos em um JSP
Aplicação(application) , requisição(request) , sessão(session) e pagina(page).
PageContext : É um subclasse de JspContext e encapsula outros objetos implícitos. Podemos usar uma
referência do PageContext para obter atributos a partir de qualquer escopo.
Obs: Os métodos referentes a atributos fica em JspContext porem as constantes para os escopos fica na
classe PageContext.
Métodos (JspContext) :
setAttribute(String, Object) : só funciona para escopo de pagina.
setAttribute(String ,Object, int escopo) : funciona em todos escopos
getAttribute(String) : só funciona para escopo de pagina.
getAttribute(String , int escopo) : funciona em todos escopos
getAttributeNamesInScope(int escopo) : todos atributos de um escopo
findAttribute(String) : quando não se sabe o escopo, este método procura do mais restrito para o
menos restrito (page, request, session e application).
EL Expression Language : oficialmente tornou-se parte da especificação a partir da JSP2.0. É um jeito
simples de invocar código Java que você normalmente faria com scriptlets e espressões. Uma expressão
EL sempre se parece com ${algumacoisa}. Para desabilitar a EL é necessario a seguinte configuração no
DD.
<web-app>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
</web-app>
scripting-invalid : <scripting-invalid> é usado para impedir que um JSP possua elementos scripting
(scriptlets, expressões e declarações). No DD
<web-app>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
</web-app>
Importante : A única forma de invalidar scripting é através da tag <scripting-invalid> no DD.
Importante: A EL e os scripting são habilidata por padrão
Importante: O atributo isElIgnored da diretiva page tem prioridade, e sempre ganha.
Ações padrões, vem em dois sabores :
Ação padrão - padrão : <jsp:include page="pagina.jsp" />
Ação padrão - não padrão : <c:set var="rate" value="80" />
Tipos de elementos JSP
Diretiva : é um recurso que você tem para dar instruções especiais ao Container no momento da
tradução da pagina. Vem em 3 tipos : page, include, taglib
-Page : Defini propriedades especificas da página. Ex: <%@ page import="foo.* , java.util.* "%>
Atributos :
import : defini import do java, alguns vem incluso como java.lang , javax.servlet , javax.servlet.http e
javax.servlet.jsp
isThreadSafe : defini se o servlet gerado precisa implementar o STM,o padrão é true, que significa que
minha aplicação é thread safe e não precisa do STM.
contentType : define o MIME type para a resposta.
isElIgnored : defini se a EL será ignorada.
isErrorPage : defini se é uma pagina de erro, o padrão é false, se for true tem acesso ao objeto implicito
exception.
errorPage : defini a URL para o recurso aonde as Throwables devem ser enviadas.
-Taglib : Defini as bibliotecas disponíveis para um JSP. Ex: <%@ taglib prefix="cool" tagdir="/WEB-
INF/tags/cool" %>
-Include : Defini a pagina que será incluido no momento da tradução. Ex: <%@ include
file="pagina.html" %>
Scriptlet : Código java dentro de um JSP que é incluso dentro de um métodos de serviço, variaveis aqui
são sempre locais.
<% Float one = new Float(42.5); %>
Expressão : Exibe o conteúdo entre as tags, este conteúdo e passado como argumento para um out do
PrintWriter que é incluso dentro de um método de serviço.
<%= "Olá" %>
Declaração : Uma decalaração JSP é sempre definida dentro da classe, mais fora do método de serviço.
As declarações servem para as variáveis estática, de instância e para os métodos. Obs : Você pode
declara um método depois a variavél, sem problemas na ordem.
<%! int y =3; %>
Template Text : HTML simplês
EL : email : ${applicationScope.mail}
Ação : <jsp:include page="pagina.jsp" />
Capítulo 8 - Páginas sem scripts
Ação Pãdrão
jsp:useBean : É uma maneira de declarar e inicializar um objeto real que você está usando em
<jsp:getProperty>.É como se você estivesse setando um atributo.
Ele procura por um atributo no scopo definido em "scope", caso ele não encontre, ele cria um. Ex:
request.setAttribute("pessoa" , p);
<jsp:useBean id="pessoa" type="foo.Pessoa" class="foo.Empregado" scope="request" >
<jsp:setProperty name="pessoa" property="name" value="Fred" />
(Funciona de forma condicional dentro do corpo, só executa se um bean não for encontrado)
</jsp:useBean>
<jsp:getProperty name="pessoa" property="name" />( Só funciona se o jsp:useBean declarar o atributo)
Obs:O atributo id do <jsp:useBean> é obrigatório.
Obs:Se você não definir o atributo scope, o padrão será page.
Obs:Se você especificar um atributo type, você só podera especificar propriedades <jsp:setProperty> no
tipo do Type e não do class.
Polimorfismo :O type é o que você declara, pode ser um tipo de classe, um tipo abstrado, interface ou
qualquer coisa que você usa como referência ao "class".
Obs:Podemos fazer combinações de ações-padrão com scripting
Obs: Erros
-<jsp:useBean id="pessoa" type="foo.Empregado" class="foo.Pessoa" /> //Ao acessar diretamente o JSP
com essa tag é gerado p seguinte erro: Erro cannot convert from Pessoa to Empregado
-Pessoa p = new Pessoa();request.setAttribute("pessoa",p);<jsp:useBean id="pessoa"
class="foo.Empregado" scope="request" /> //foo.Pessoa cannot be cast to foo.Empregado
O atributo Param : Você pode enviar um parâmetro de solicitação direto para um bean.
Ex: <jsp:setProperty name="pessoa" property="name" param="name" />.
Se o nome do parâmetro da solicitação for igual o nome da propriedade do bean e você não especificar
o value e nem o param o valores são diretamente preenchidos.
Ex: <jsp:setProperty name="pessoa" property="name" />.
Se TODOS os nomes de parâmetros da solicitação coincidir com os nomes da propriedades, todos são
preenchidos, caso não encontre algum apenas não sera preenchido.
Ex: <jsp:setProperty name="pessoa" property="*" /> //As tags do bean convertem as propriedades
primitivas automaticamente.
Importante: O bean deve ter um construtor publico sem argumento, ou seja seguir a "Lei do Bean",
caso contrário é gerado um erro
Importante: Se o type for usado sem um class , só irá funcionar se o bean já existir (O container
NUNCA tenta instaciar um type mesmo se ele for concreto), se o class for usado (com ou sem o type),
a classe dever ser concreta e possuir um construtor padrão
Importante: A conversão automática String-Primitiva NÃO funciona se você usar scripting.
<jsp:setProperty name="pessoa" property="id" value="<%= req.getParameter("id")%>" />// Isto gera
um erro porque id é inteiro, se fosse String funcionaria.
EL Expression Language.
A EL facilita a exibição de propriedades aninhadas, ou seja propriedades de propriedades ,o que não é
possível com <jsp:getProperty> sem uma classe especial.
A primeira variável na expressão ou é um objeto implícito ou um atributo(que pode ser definido pelo
"jsp:useBean" ou algum "setAttribute").
Objetos implícitos EL.
pageScope:Um Map dos atributos do escopo da pagina.
requestScope:Um Map dos atributos do escopo da solicitação
sessionScope : Um Map dos atributos do escopo da sessão
applicationScope : Um Map dos atributos do escopo da aplicação
param : Um Map dos parâmetros da solicitação
paramValues:Um Map dos parâmetros da solicitação
header : Um Map dos header da solicitação
headerValues : Um Map dos header da solicitação
cookie : Um Map para cookies Ex: ${cookie.username.value}
initParam : Um Map para os parâmetros init do contexto.
pageContext : De todos os objeto implícitos apenas o pageContext não é um mapeamento.Ele é uma
referência ao um objeto real.
Obs: Os objetos implícitos EL não são os mesmo disponíveis para os scripts JSP, exeto o pageContext.
Operadores EL
Operador ponto "." : O que está a esquerda DEVE ser ou um Map ou um Bean, e o que está na direita
DEVE ser uma chave de um Map ou uma propriedade de um Bean, e seguir as regras normais de
nomenclatura java(Deve inicia com letra, _, $ depois do primeiro caracter pode ter número, não pode
ser uma palavra chave java).
Operador [] : O que está a esquerda pode ser um Map, bean um List ou um array e o que vai na direita
não precisa seguir as regras de nomenclatura java e ser for um String literal (entre aspas) ela pode ser
uma chave map, um propriedade bean, ou ainda um índice dentro de uma List ou array.
Obs: Um índice String é forçado no int para os arrays e Lists, caso ele não possa ser forçado isto gerará
um erro.
Obs: Se o que for entre os [] não for uma String literal, o Container avalia buscando por um atributo, se
ele não encontrar, retornará nulo.
Obs: Os indice dos Lists e arrays iniciam do 0, em Maps eles iniciam do 1.
Obs: Na EL, na expressão e a ação padrão "getProperty" apresenta o texto bruto para o HTML, por
exemplo <b></b> não é apresentado na pagina, é necessário converter os caracteres em seus
respectivos formatos. Ex :"<".
Operadores Aritméticos
Adição : +
Subtração : -
Multiplicação : *
Divisão : / e div (Você pode dividir por 0 na EL o resultado é infinito)
Resto : % e mod (você não pode usar o operador resto com zero, você terá um exceção.)
Operadores Lógicos
AND : && e and
OR : || e or
NOT : ! e not
Operadores relacionais
Igual : == e eq
Diferente : != e ne
Menor que : < e it
Maior que : > e gt
Menor ou igual a : <= e le
Maior ou igual a : >= e ge
Palavra reservadas EL : true, false, null, instanceof (reservada para o futuro), empty(retorna verdadeiro
se algo é nulo ou vazio).
Importante: A EL trata os valores nulos graciosamente, sem gerar exceções, Nas expressões
aritméticas a el trata uma variável desconhecida como zero e nas expressões lógicas como false.
Funções EL : É um classe java simple com um método público e estático e pode ter argumentos com o
nome totalmente qualificados, o método deveria(mais não é obrigatório) ter um tipo de retorno.A
função dever ter um TLD que defina a função usada no JSP, o nome usada na EL não precisa ser igual o
nome do método, e é no TLD que você mapeia isso.
Ex: no TLD
<taglib...>
<tlib-version>1.0</tlib-version>
<uri>funcoesDados</uri>
<function>
<name>jogarDados</name>
<function-class>foo.Dado</function-class>
<function-signature>jogar()</function-signature>
<function>
</taglib>
No JSP.
<%@ taglib prefix="dados" uri="funcoesDados" %>
${dados:jogarDados()}
Templates : Existe três mecanismo de includes diferente , iremos ver dois, a diretiva include e a ação-
padrão <jsp:include/>
-Diretiva include : Diz ao Container o seguinte, copie tudo do arquivo incluído e cole neste arquivo, bem
aqui. Durante a tradução
Ex: <@% include file="header.jsp" %>
Vantagem : Performance
Desvantagem: Os dados não estará atualiados e a classe do Servlet ficará maior.
-Ação Padrão <jsp:include/> : Diz ao Container o seguinte, insira a RESPOSTA do arquivo incluído aqui, e
continue com o restante. DURANTE O RUNTIME. O mais
Ex: <jsp:include page="header.jsp" />
Vantagem : Os dados sempre estará atualiados.
Desvantagem: Performance
Obs : O Container faz um RequestDispatcher para a pagina a ser incluída chamando o método include()
do RequestDispatcher.
<jsp:param> : Pode ser usado somente corpo do <jsp:include> ou <jsp:forward> para passar
parâmetros(Infomações).Se o nome do parâmetro já tiver um valor na solcitação este será substituído.
Ex: <jsp:include page="header.jsp">
<jsp:param name="titulo" value="Titulo da pagina">
</jsp:include>
e na pagina incluída ${param.titulo}
<jsp:forward>:Você pode encaminhar de um JSP para outro,ou de um JSP para um servlet,ou de um JSP
para qualquer outro recurso da sua aplicação. Com o <jsp:forward> o buffer é limpo antes do
encaminhamento, ou sejá nada que você escrever antes do encaminhamento aparecerá , se ele for
realizado.
Ex: <jsp:forward page="logout.jsp" />
Importante: se você fizer um flush(); e chamar o forward, tudo que estava antes do forward é exibido
para o cliente e nada mais, o container lança uma IllegalStateException mais o cliente não ve ela na
pagina.
Importante: A diretiva include insere a FONTE do arquivo no momento da tradução, mais a ação
padrão <jsp:include/> insere a RESPOSTA do arquivo no runtime.
Obs: Ambos mecanismo de inclusão podem incluir paginas JSPs e HTMLs.
Obs: Os JSP incluído pode possuir seus próprios conteúdos incluidos.
Obs: Existe algumas limitaçoes para arquivos incluídos, eles não pode altera código do status da
resposta nem criar headers, nem chamar o addCookies().
Obs: Não coloque HTML de abertura e fechamento e tags BODY dentro das suas paginas incluídas, pois
não ira funcionar em todos Browsers.
Capítulo 9 - Tags Customizadas
JSTL 1.1 centrais - São Tag Customizadas prontas para iteragir com seu JSP. Não faz parte da
especificação JSP2.0.
TAG: <c:forEach> :Tag que integra-se perfeitamente a um loop for que interage em uma coleção(Map,
Coleção, array ou String delimitada por vírgula)
Ex:<c:forEach var="movie" items="${listMovie}" varStatus="movieCount">
${movieCount.count}
${movie}
</c:forEach>
Atributos:
-var : A variável que armazena o objeto da coleção, tem apenas escopo de tag.
-items : a coleção.
-varStatus :é uma instância de javax.servlet.jsp.jstl.core.LoopTagStatus que contem o atributo count
Obs: Você pode aninha tags <c:forEach>, tr é linha, td é coluna.
TAG: <c:if> : Realiza um test condicional, é como um "if"
Ex:<c:if test="${userType eq 'member'}"> Acesso permitido </c:if>
Atributos:
text : condição booleana
TAG: <c:choose> : Realiza um test condicional Se Não realiza outro, é como um "if" , "else".
Ex:<c:choose>
<c:when test="${userType eq 'member'}" >
Acesso permitido
<c:when>
<c:otherwise>
Acesso não permitido
</c:otherwise>
<c:choose>
TAG: <c:out> : Tag para exibir texto. Proteje contra o ataque de hack com cruzamento de sites, pois
código javascripts não são interpretados na saída do c:out.
Concorrentes:expressões ,<jsp:getProperty> e EL ,em todas essas os texto não são convertidos e não é
possível definir um valor padrão caso os texto seja nulo.
Ex: <c:out value='${pageContext.currentTip}' default="Tipo padrão" />
Atributos:
-escapeXml : O padrão é true, isso quer dizer que os caracteres serão convertidos para XML, ou seja o
browser apresentará caracteres como <,>,&,'," .
-default ou <c:out value='${user}'>user</c:out> : defini um valor padrão caso o value for avaliado para
null.
TAG: <c:set> : Essa tag é usada para definir um valor em um Map , propriedade em um bean, e criar um
atributo no escopo definido .
Concorrentes:<jsp:setProperty> só é capaz de fazer uma coisa: definir a propriedade de um bean.
Pode ser usada de duas formas com var OU com target.
-Versão var : serve para definir variáveis de atributos.
Ex:<c:set var="user" scope="session" value="Cowboy" />
Atributos:
var : Obrigatório, Se NÃO houver um atributo no escopo sessão chamado "user", está tag cria um , mais
só se o valor não for nulo .
value : testar para ver se é Obrigatório se não especificado no corpo o valor do atributo.
scope : Opicional, O padrão é o de pagina.
Importante: Se o valor de value ou o corpo for avaliado como nulo, e existir um atributo com o
mesmo nome do var, ele será removido do scopo, se o scopo não for espeficicado ele começará
olhando da pagina, request, sessão e aplicação.
- Versão target: serve para definir propriedades de beans e valores de Maps.
Ex:<c:set target="${pessoa}" property="name" value="Cowboy" />
Atributos:
target : Obrigatório, Não pode ser uma String literal, Se for nulo ou não for um Map nem um Bean o
container gera uma Exceção.
property : Se for um bean defina o nome da propriedade, se for um Map defina o nome da chave.
value : testar para ver se é Obrigatório, se não especificado no corpo o valor do atributo.
Scope : Opicional, O padrão é o de pagina.
Importante: O container gera uma exceção se o target for nulo , não for um Map, não for um Bean,e
se for uma Bean MAIS a propriedade não igual ao property.
TAG: <c:remove> : usado para remover um atributo.
Ex:<c:remove var="user" scope="request" />
Atributos:
var :obrigatório, o nome do atributo, DEVE SER UMA STRING LITERAL.
scope : Opicional, O padrão é o de pagina.
TAG <c:import/> : é um tipo de include dinâmico, o arquivo que será incluido pode se localizar dentro
ou fora do container. Durante a solicitação
Ex:<c:import url="http://www.google.com.br" />
Concorrentes: a diretiva include <%@ include file="header.html" %> , e a ação padrão include
<jsp:include page="header.jsp" />
Atributos:
url : url que será inclusa, pode se localizar dentro ou fora do container
TAG <c:param/> :Pode ser usado no corpo do <c:import/> para passar parâmetros(Infomações).Se o
nome do parâmetro já tiver um valor na solcitação este será substituído.
Concorrentes: <jsp:param>
Ex:<c:import url="header.jsp" >
<c:param name="titulo" value="Hello people" />
</c:import>
e na pagina incluída ${param.titulo}
TAG <c:url/> : usado para criar um link, realiza a reescrita da url automáticamente caso o cliente não
aceitar cookies.
Ex: c:url value="/inputComments.jsp" var="valorUrl"/>
Concorrentes: scripting Ex: <a href="\<% response.encodeURL("/BeerTest.do")%>\" >click </a>
Atributos:
value : A url do link.
Var : opcional, use este atributo caso queira acessar o valor de value posteriormente.
Obs:O <c:url> realiza a reescrita da url automaticamente, porem não realiza a codificação.A codificação
de url significa substituir o caracteres não seguros\reservados por outros caracteres,e então, toda
pagina é decodificada novamente no lado do servidor.Por exemplo,não são permitidos espaços em
URL,mais você pode substituir por "+" ou seja ao invès disso
<c:url value="/inputComments.jsp?first=${first}" precisamos forçar o c:url codificar a URL, precisamos
usar o <c:param> em seu corpo. Ex:
<c:url value="/inputComments.jsp" var="valorUrl"/>
<c:param name="primeiroNome" value="${first}" />
</c:url>
TAG <c:catch/> : Semelhante a try/catch do java, serve como try(tentar) e como capturar(catch).
Ex:<c:catch var="myException">
<% int x = 10/0; %>
</c:catch>
Atributos :
var : opcional, um objeto var é uma instância de Throwable e possui a propriedade message com escopo
de pagina.
Importante : nada roda dentro do corpo de um <c:catch> após a exceção.
TAG <c:forTokens> : permite fazer iterações sobre tokens nos quais VOCê defini um delimitador.
Funciona da mesma forma que o StringTokenizer.
TAG <c:redirect> : ?
Erros
Diretiva page : usada para definir paginas de erro
Atributos :
isErrorPage : se true confirma ao container que está é uma pagina de erro. Ex: <%@ page
isErrorPage="true" %>
errorPage : Caso acontecer uma exceção em uma pagina que tenha este atributo, a solicitação sera
encaminhada para a pagina de errorPage.Ex: <%@ page errorPage="paginaErro.jsp" %>
Objeto implícito :Em um scriptlet você terá um objeto implícito "exception" e com EL
"${pageContext.exception}". o objeto exceção implícito fica disponível apenas para
paginas de erro com a diretiva page explicitamente definida, Em outras palavras, configurar o pagina de
erro no DD não é o suficiente.
TAGs
TLD : É um descritor de bibliotecas de tags, e descreve duas coisas principais: Tag customizada e funções
EL.A classe handler, o TLD e o JSP são os três elementos que você precisa para distribuir e rodar uma
aplicação web que usa tag.
<taglib...>
<tlib-version>1.0</tlib-version>// Obrigatório (A Tag não o valor)
<short-name>funções</short-name>// Obrigatório, para uso de ferramentas
<uri>funcoesDados</uri> // Opcional ,O uri é um identificador único de no TLD, ou seja , é o nome
único para a bibliotecas de tags que o TLD descreve.Porem se você NÃO
especificar um <uri> dentro do TLD, o container tentará usar o atributo uri
da diretiva taglib como um caminho para o próprio TLD.
<function>
<name>jogarDados</name>
<function-class>foo.Dado</function-class>
<function-signature>jogar()</function-signature>
<function>
<tag>
<description>função advice</description>// Obrigatório
<name>advice</name>// Obrigatório
<tag-class>foo.AdviceHandle</tag-class>// Obrigatório
<body-content>empty</body-content>// Obrigatório
<attribute>
<name>user</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>// Opcional,Se true , o atributo pode ser um valor de expressão em
runtime, ou seja, não precisa ser uma String literal.
<type>foo.User</type>// Opcional, usa o nome totalmente qualificado como tipo do atributo que
conhecida com o método "Set" do Handler.
</attribute>
</tag>
</taglib>
Atributo - <rtexprvalue> : Você pode usar três tipos de expressões para o valor de um atributo (ou
corpo da tag), que permita expressões em runtime.
1-)Expressões EL : <my:advice user="${user}" />
2-)Expressões Scripts : <my:advice user='<%=request.getAttribute("user") %>' />
3-)Ações Padrões : <my:advice>
<jsp:attribute name="user">${user}</jsp:attribute>
</my:advice>
Importante :O <jsp:attribute> pode ser inserido em um tag mesmo se o seu corpo estiver declarado
como empty, e o valor do seu atributo name é o nome do atributo da tag externa.
Atributo - <body-content> : Defini informações sobre o corpo da Tag, existe quatro tipos.
<body-content>empty</body-content> // A tag não pode ter um corpo.
<body-content>scriptless</body-content> // A tag não pode ter elementos scripts , mais pode ter texto,
templates, el , ações padrões ou customizadas.
<body-content>tagdependent</body-content> //Somente texto puro.
<body-content>JSP</body-content> // Pode ser qualquer coisa que possa ser inserida em um JSP.
Existe três maneira de invocar uma tag com o corpo vazia, sao elas:
1-)<my:advice user="${user}" />
2-)<my:advice user="${user}"></my:advice>
3-)<my:advice>
<jsp:attribute name="user">${user}</jsp:attribute>
</my:advice>
Localização do TLD.
Antes do JSP 2.0 : Era necessário especificar um mapeamento no DD entre o <uri> do TLD e a real
localização do arquivo TLD.
<web-app>
<jsp-config>
<taglib>
<taglib-uri>funcoesDados</taglib-uri>// O que você usa no atributo uri da diretiva taglib
<taglib-location>/WEB-INF/myFuncoes.tld<taglib-location> // A localização real do TLD
<taglib>
<jsp-config>
</web-app>
Depos do JSP 2.0 : O Container automaticamente cria um mapa entre o arquivo TLD e nome <uri>.
Se você de fato especificar uma <taglib-location> explícita no DD, o Container JSP2.0 irá usá-la.
Quatro lugares onde se o Container procura por TLDs.
1-)Diretamente dentro de WEB-INF
2-)Diretamente dentro de um subdiretório de WEB-INF
3-)Dentro do diretório META-INF em um arquivo JAR, que fica no interior de WEB-INF/lib
4-)Dentro de um subdiretório de META-INF em um arquivo JAR, que fica no interior de WEB-INF/lib
Obs: Não use prefix para taglibs que esteja na lista reservada(jsp , jspx, java, javax, servlet, sun , sunw).
Capitulo 10 - Desenvolvendo tag customizadas.
Tag Files : Implementa funcionalidade da Tag em outra pagina usando JSP. Adicionado na JSP 2.0 , é um
tipo de "tag handler junior", ou menos especificos, são includes "bombados".Apenas someando um
arquivo .jsp a ser incluído para .tag e colocando o arquivo em seu lugar correto, este já se torna uma
Tag File.O nome da tag é o mesmo nome do arquivo. Ex: um arquivo header.tag
<%@ taglib prefix="myTag" tagdir="/WEB-INF/tags" %>
<myTag:header/>
Atributos : Os Tag Files usam diretivas attribute para atributos.
Ex:<%@attribute name="titulo" required="true" rtexprvalue="true" %> e na tag <myTag:header
titulo="Olá Mundo"/>
Obs: O valor do atributo name da diretiva attribute é o nome do atributo usado na Tag.
Atributos dinamicos : Os Tag Files usam a diretiva tag para atributos dinamicos. Ex:
<%@ tag dynamic-attributes='tagAttrs' %> // o valor do atributo é uma variável no escopo de pagina
que mantem um hashmap.
Importante: Os atributos de tag customizadas são declarados no TLD, as Tag File usam a diretiva
attribute.
Importante: Se você tiver um atributo como required="true" e não usar ele na tag, o container lança
uma exceção "status 500".
Importante: No <jsp:include> e <c:include> as informações são enviadas por PARÂMETROS de
solicitação, assim qualquer parte da aplicação consegui vê-la,com tag files as informações são passada
como atributo de escopa de tag.
Corpo : Aúnica maneira de declara um corpo para uma Tag é usando a diretiva "tag" com atributo body-
content. Geralmente um corpo é usado, quando as informações a serem processadas é muito grande e
não é possível fazer o mesmo usando a diretiva attribute.
<body-content> : define o conteúdo do corpo da tag, diferente das tag customizadas na Tag Files esse
atributo não é obrigatório, e seu padrão é scriptless.
Existe três valores possível para o body-content : empty, tagdepentent e scriptless, ou sejá nunca será
permitido scripting em Tag Files.
Localização : Existe 4 lugares que os Tag Files devem residir.
1-)Diretamente dentro de WEB-INF/tags
2-)Dentro de um subdiretório de WEB-INF/tags
3-)Dentro do diretório META-INF/tags em um arquivo jar, que ficar no interior de WEB-IF/lib
4-)Dentro do subdiretório META-INF em um arquivo jar, que ficar no interior de WEB-IF/lib
Importante: Se os Tag Files forem distribuídos em um jar , obrigatóriamente ele devem ter um TLD.
Importante: Os Tag Files, tem acesso aos HttpServletResponse, HttpServletRequest, e o JspContext
super classe de PageContext.
Importante: Você não pode usar scripting no corpo de um Tag File mais pode usar dentro do arquivo
.tag.
Importante: O TLD para um Tag File, descreve apenas a localização dos .tag nada mais.Se você criar
um TLD para as TAGs File, mesmo combinada com tag customizadas o Container considerará tanto os
tags files quanto as tags customizadas.
Ex:
<taglib...>
<tlib-version>1.0</tlib-version>
<uri>myTag</uri>
<tag-file>
<name>header</name>
<path>/META-INF/tags/header.tag</path>
</tag-file>
</taglib>
Tag Handler : Implementa funcionalidades da tag com uma classe java especial, é simplesmente um
classe java que faz o trabalho da tag.
Tag Handler Simples : Adicionado na JSP 2.0, é uma classe que extende a SimpleTagSupport e
implementa o método doTag() que declara um JspException e IOException(não precisa embrulhar o
print em try/catch).
<taglib>
<tlib-version>1.0</tlib-version>
<uri>myTag</uri>
<tag>
<description>Simple Tag</description>
<name>simple</name>
<tag-class>foo.SimpleTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>list</name>O mesmo nome declarado como propriedade na classe handler e como atributos da tag
<required>true</required>
<rtexprvalue>true</rtexprvalue>//Opcional ,Se true , o atributo pode ser um valor de expressão em
runtime, ou seja, não precisa ser uma String literal.
<type>foo.User</type>// Opcional, usa o nome totalmente qualificado como tipo do atributo que
conhecida com o método "Set" do Handler.
</attribute>
</tag>
</taglib>
Para processar o corpo é necessário usar o getJspBody().invoke(null) dentro do doTag(), o argumento
null, diz para o output ir para resposta, em vez de algum outro write que você informe.
JspTag<interface> -> SimpleTag<interface> -> SimpleTagSupport<classe> (inclui 3 métodos incluindo o
getJspBody()), em 99,9999% iremos extender a SimpleTagSupport.
Ciclo de vida
Quando um JSP invoca uma tag, uma nova instacia da classe é criada, e quando o método doTag()
finaliza o objeto handler desaparece(handler não são reutilizados)
1-) Carrega a classe
2-) Executa o construtor
3-) chama o setJspContext(JspContext)
4-) Se estiver aninhada ,chama o setParent(JspTag)
5-) Se tiver atributos, chama o set dos atributos
6-) Se a tag não for declarada com body-content empty e tiver um corpo chama o JspBody(JspFragment)
7-) Chama o doTag(), você sempre substituirá isso.
JspFragment : É um objeto que representa o código JSP, trata-se de algo que serve para rodar e gerar
um output, O corpo da tag que invoca um Handler Simples e é encapsulado no objeto JspFragment e
então passado como argumento no método setJspBody(JspFragment).
O JspFragment tem dois métodos
-JspContext getJspContext()
-void invoke(java.io.Writer)
SkipPageException : É uma execeção usada para Tag Handler Simples, a pagina é avaliada parcialmente
até o ponto da exceção.
Quando a página incluída gera uma SkipPageException, somente ela será interrompida.
Importante: Não pode conter quaisquer elementos de script.
Importante: Se você colocar algum conteúdo dentro de um tag declarada como body-content empty,
o Container gera um exceção.
Importante: Se um atributo não for um tipo primitivo ou uma String literal, o valor de <rtexprvalue>
deve ser true.
Importante: O setJspBody() é invocado somente se esta duas coisas forem verdadeiras:
1-) A tag NÃO está declarada como body-content empty
2-) A tag tiver um corpo ou seja: não deve ser uma tag vazia como <foo:bar/> e <foo:bar></foo:bar>
Tag Handler Clássica : É usado na era pré JSP2.0, é uma forma mais complexas de escrever tags
customizadas, geralmente extendemos a TagSupport ou BodyTagSupport
Importante:As tags clássica herdam de TagSupport um variável pageContext em contrasnte do
método getJspContext() da simple TAG.
Importante:O doStartTag não declara uma IOException , então devemos embrulhar o print com
try/catch
Importante:O doStartTag() ,doAfterBody() e o doEndTag() retorna um int.
Ciclo de vida
1-) Carrega a classe
2-) Executa o construtor
3-) chama o setPageContext(PageContext)
4-) Se estiver aninhada ,chama o setParent(Tag)
5-) Se tiver atributos, chama o set dos atributos
6-) Chama o método doStartTag()
7-) Se a tag NÃO for declarada com body-content empty, tiver um corpo e doStartTag() retorna
EVAL_BODY_INCLUDE o corpo é avaliado
8-) Se o corpo for avaliado chama o doAfterBody()
9-) Chama o método doEndTag().
-IterationTag
Possíveis valores retornados quando se estende a TagSuport, exceto a constante EVAL_BODY_AGAIN,
todas as outras são declaradas na interface Tag
doStartTag() : SKIP_BODY, EVAL_BODY_INCLUDE
doAfterBody(): SKIP_BODY, EVAL_BODY_AGAIN (Está é a única constante declarada em TagSuport).
Obs:O método doAfterBody() é da interface IterationTag
doEndTag() : SKIP_PAGE, EVAL_PAGE
Valores padrão retornados pela TagSupport .
doStartTag() : SKIP_BODY
doAfterBody(): SKIP_BODY
doEndTag() : EVAL_PAGE
A classe TagSupport supões que a sua tag não tem um corpo, ou que, se o corpo for avaliado, ele deve
ser avaliado apenas UMA VEZ, e tambem supões que você sempre deseja que o resto da página seja
avaliado.
Importante: Se você quiser que o corpo seja avaliado você deve sobreescrever o doStartTag() para
retornar EVAL_BODY_INCLUDE.
Importante: Diferente dos Tag simples, os clássicos da reutilizados, então tome em declarar variaveis
de instancia ao inves de locais.
DynamicAttributes : é um interface para armazenamento dinamico de atributos, é usado tanto para
Simple Tag quanto para Classica Tag, atributos opcionais e que não tenha o método set definido será
implementado pela DynamicAttributes . Método : setDynamicAttribute(String uri, String name, Object
value)
TLD:<dynamic-attributes>true</dynamic-attributes>
Os atributos dinamicos aceitam EL, ou <%= %>
-BodyTag :É usado para fazer algo com o conteúdo propriamente dito do corpo e fornece mais dois métodos, setBodyContext e doInitBody. Possíveis valores retornados quando se estende a BodyTagSupport ,exceto a constante EVAL_BODY_INCLUDE e EVAL_BODY_BUFFERED, todas as outras são declaradas na interface Tag doStartTag() : SKIP_BODY, EVAL_BODY_INCLUDE, EVAL_BODY_BUFFERED setInitBody() e doInitBody() : EVAL_BODY_BUFFERED doAfterBody(): SKIP_BODY, EVAL_BODY_AGAIN doEndTag() : SKIP_PAGE, EVAL_PAGE Valores padrão retornados pela BodyTagSupport . doStartTag() : EVAL_BODY_BUFFERED setInitBody() e doInitBody() : EVAL_BODY_BUFFERED doAfterBody(): SKIP_BODY doEndTag() : EVAL_PAGE Importante : Se o TLD, não estiver dizendo que o corpo é vazio e você invocar a tag estando vazia, os métodos setInitBody e doInitBody não são chamados. Importante : Se o TLD for declarado tendo um corpo vazio, você deve retornar SKIP_BODY do método doStartTag(), intependente de você implementar IterationTag ou BodyTag Obs : Mais detalhes pagina 566 e 576 Tag Parent : Tanto a SimpleTag como a Tag têm um método getParent(). O getParent() de Tag retorna uma Tag, mais o getParent de Simpletag retorna uma instancia de JspTag. getParent() : retorna a tag externa a tag "pai", você pode iterar e descobri até onde vai o aninhamento, se o método retornar null, então estamos no nivel mais alto, e não temos um parent. Importante : Tag Simples pode acessar um parent tanto simples quanto clássico, porem as tag clássica podem ter somente parent classicos. findAncestorWithClass(tagInicial,classeParent): Existe tanto em TagSupport quanto em SimpleTagSupport e é usado quando, digamos, pular alguns níveis de aninhamento e ir direto a um grandparent. EX:findAncestorWithClass(this, WayOuterTag.class)
Capítulo 11 - Distribuição
WAR significa Web ARchive, o WAR é um jar com uma extensão .war em vez de .jar.
Para o Container quase não importa se a aplicação é distribuida dentro ou fora de um WAR, a estrutura
é a mesma. A única diferença significativa é que um WAR terá um diretório META-INF sob o contexto da
aplicação que pode ter um arquivo MANIFEST.MF que você pode declara dependências de bibliotecas o
qual lhe fornece uma verificação em tempo de distribuição, se o Container não puder fornecê-las, ele
não deixará distribuir a aplicação com sucesso. O que é muito melhor do que se você distribuísse a
aplicação e só depois descobrisse em tempo de solicitação, ao receber algum erro de runtime horrível.
Regras de Localização
Deployment Descriptor (web.xml) : Dentro do WEB-INF
Tag Files(.tag ou .tagx) : Fora de um jar devem estar dentro de WEB-INF/tags ou subdiretório, em um jar
(com TLD) devem estar em META-INF/tags ou subdiretório.
HTML e JSPs(diretamente acessíveis) : qualquer lugar sob a raiz da aplicação web, EXETO sob WEB-INF,
e META-INF em um arquivo war.
HTML e JSPs(não acessíveis) : WEB-INF e META-INF em um arquivo war.
TLDs : Fora de um jar devem estar dentro de WEB-INF ou subdiretório, em um jar devem estar em
META-INF ou subdiretório.
Classes dos Servlets : WEB-INF/classes e que a estrutura de diretório coincida com a estrutura de
pacotes, ou nos diretórios apropriados dentro de um jar.
Classes dos Tags Handlers : WEB-INF/classes e que a estrutura de diretório coincida com a estrutura de
pacotes,ou nos diretórios apropriados dentro de um jar
Arquivos JAR : WEB-INF/lib
Importante - Se o servidor receber um solicitação do cliente pedindo qualquer coisa localizada sob
WEB-INF ou META-INF, o Container deve responder com um erro 404 not found.
Importante - O Container sempre procurará classes no diretório WEB-INF/classes antes de procurar
em arquivos JAR em WEB-INF/lib.
Importante - Para acessar arquivos de texto, JPG , etc dentro do JAR, vocÊ precisa usar os métodos
getResource() ou getResourceAsStream do J2SE, não é especifico do Servlet. Agora você poderia
reconhecer esses dois métodos porque eles existem na API do ServletContext, porem esses só
funciona para recursos que não são distribuidos em arquivo JAR.
Mapeamentos de Servlets, 3 tipos.
1)Combinação EXATA : <url-pattern>/Beer/SelectBeer.do</url-pattern>, obrigatório começar com "/".
2)Combinação de DIRETÓRIO : <url-pattern>/Beer/*</url-pattern>, obrigatório começar com "/".
3)Combinação de EXTENSÃO : <url-pattern>*.do</url-pattern>, obrigatório começar com "*", nunca
com "/".
Importante - O Container procura na ordem acima, se uma solicitação combinar com diretórios de
mais de um <url-ele escolhe o mapeamento mais longo.
Arquivos de Boas vindas no DD.
Funcionamento : Ao receber um solicitação o Container procura no DD por um mapeamento por
Servlet, caso não encontre ele procura em <welcome-file-list> em ordem de declaração dos <welcome-
file>, ele compara o arquivo do <welcome-file> com o do caminho da solicitação. O container escolherá
a primeira combinação que achar começando pelo primeiro arquivo de boas vindas listado em
<welcome-file>.
<web-app>
<welcome-file-list>// Permitido apenas um <welcome-file-list> por DD.
<welcome-file>index.html</welcome-file>// NÃO podem começar e nem terminar com "/"
<welcome-file>default.jsp</welcome-file>
<welcome-file-list>
</web-app>
Configuração Erro no DD.
Declarando uma pagina de erro para um exceção
<web-app>
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/arithmeticError.jsp</location>
</error-page>
</web-app>
Declarando uma pagina de erro para um código de status HTTP
<web-app>
<error-page>
<error-code>404</error-code>
<location>/arithmeticError.jsp</location>
</error-page>
</web-app>
Importante - Você não pode usar <exception-type> e <error-code> juntos na mesma tag <error-page>
Importante - Você deve usar o nome da classe totalmente qualificada em <exception-type>
Configuração da inicialização do Servlet
Qualquer valor não negativo para o <load-on-startup> diz ao Container para inicializar o servlet quando
a aplicação é distribuida, o valor de <load-on-startup> determina a ordem que os servlets serão
carregados, se tiver dois o mais servlets com o mesmo valor o Container escolhe a ordem.
No DD
<web-app>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>foo.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
Paginas JSP VS Documento JSP
Documentos JSP : só pode conter sintaxe XML do documento JSP
Paginas JSP : pode conter tanto sintaxe XML do JSP como outras coisas (HTML, Scripting, etc).
Tabelas de comparações
Diretivas : <%@ page import="java.util.*" %> <jsp:directive.page import="java.util.*"/>
Declarações : <%! int y =3; %> <jsp:declaration>int y =3;</jsp:declaration>
Scriptlet : <% list.add("Fred"); %> <jsp:scriptlet>list.add("Fred");</jsp:scriptlet>
Expressão : <%= it.next() %> <jsp:expression>it.next()</jsp:expression>
Texto : There is no spoon. <jsp:text>There is no spoon.</jsp:text>
Tags relacionadas ao EJB no DD
EJB Local : Significa que o cliente(Neste caso Servlet) e o bean(EJB) esta rodando na mesma JVM
<ejb-local-ref>
<ejb-ref-name>ejb/Customer</ejb-ref-name>//Nome de busca JNDI
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>foo.CustomeHome</local-home>//Deve ser nomes completamente qualificados das interfaces
<local>foo.Custome</local>// Deve ser nomes completamente qualificados das interfaces
</ejb-local-ref>
EJB Remoto : Significa que o cliente(Neste caso Servlet) e o bean(EJB) esta rodando em diferentes JVMs
<ejb-ref>
<ejb-ref-name>ejb/Customer</ejb-ref-name>//Nome de busca JNDI
<ejb-ref-type>Entity</ejb-ref-type>
<home>foo.CustomeHome</home>// Deve ser nomes completamente qualificados das interfaces
<remote>foo.Custome</remote>// Deve ser nomes completamente qualificados das interfaces
</ejb-ref>
Tag <resource-ref> :
<resource-ref>
<description>Primary database</description>
<res-ref-name>jdbc/primaryDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>CONTAINER</res-auth>
</resource-ref>
Tags JNDI <env-entry> do DD.
São tags entrada de ambiente, é parecido com uma constante em tempo de distribuição da aplicação.
<env-entry>
<env-entry-name>taxas/taxasDiscontos<env-entry-name>// nome de busca que você usará no loockup
<env-entry-type>java.lang.Integer<env-entry-type>//Qualquer tipo que use uma única String como
parâmetro no construtor, (ou um único Character)
<env-entry-value>10<env-entry-value>//Será passado como String ou Character
</env-entry>
Importante: o <env-entry-type> não pode ser um tipo primitivo.
Tag <mime-mapping> do DD
<mime-mapping>
<extension>mpg</extension> // NÃO tem ponto "."
<mime-type>video/mpeg</mime-type>
</mime-mapping>
Capítulo 12 - Segurança
Autorização
Definindo papéis
O realm (ou reino) da segurança , conforme a especificação do servlet é um lugar aonde as informações
de Autenticação são armazenadas ex:(LDAP, BD, Arquivos).No tomcat é usado o tomcat-users.xml (Varia
conforme o fabricante)
<tomcat-users>
<role rolename="Guest"/>
<role rolename="Member"/>
<user name="Bill" password="coder" roles="Member, Guest"/>
</tomcat-users>
No Web.xml é necessário mapear os papéis, especifico do fabricante em questão, pois o container cria
uma mapeamento entre o security-role e o realm
<web-app>
<security-role>
<role-name>Guest</role-name>
</security-role>
<security-role>
<role-name>Member</role-name>
</security-role>
</web-app>
Defindo restrições de recursos/métodos
<web-app>
<security-constraint>
<web-resource-collection>//Obrigatório, pode ter um ou mais na mesma security-constraint
<description>Descrição</description>//Opcional
<web-resource-name>Update</web-resource-name>//Obrigatório usado por ferramentas
<url-pattern>/Beer/AddRecipe/*</url-pattern>//Obrigatório ter ao menos um ou mais
<http-method>POST</http-method>//Opcional, se não for declarado, então TODOS metodos HTTP são restringidos
</web-resource-collection>
<auth-constraint>//Opcional,se existir obrigatóriamente o container deve realizar a autenticação, caso contrario
o container deve permitir acesso não autenticado a TODOS usuarios.
<description>Descrição</description>//Opcional
<role-name>Guest</role-name>//Opcional, se conter *, TODOS usuários são permitidos
<role-name>Member</role-name>Opcional,Se não existir este elemento em auth-constraint então nenhum user é permitido
<auth-constraint>
<security-constraint>
</web-app>
Obs:Elementos conflitantes pagina 671.
Segurança Programática
HttpServletRequest contem 3 metodos sobre segurança.
getUserPrincipal() : é usado principalmente com EJB
getRemoteUser() : é usado para verificar o status da autenticação
isUserInRole() : é usado para autorizar partes de um método, Antes de ser chamado o user precisa se
autenticado, caso contrario sempre retornara false.
Caso o papel usado pelo servlet seja diferente do papel usado pelo security-role no web.xml, será
necessario realizar um link entre ambos.
<web-app>
<servlet>
<security-role-ref>
<role-name>GuestServlet</role-name>
<role-link>Guest</role-link>
<security-role-ref>
</servlet>
</web-app>
O containe procura PRIMEIRO por um security-role-ref correspondente. OBS(Testar se é obrigatório ter
um role-link quando usa papeis pelo servlet)
Autenticação
Funcionamento - O Browser realiza uma solicitação ao servidor, se o recurso da solicitação for restrito o
servidor retorna um HTTP 401(Unauthorized) com um HEADER www-authenticate e informações do
realm, o browser recebe 401 e baseado nas informações do Realm pede o usuario e senha e envia a
solicitação ao servidor, mais desta vez inclui um HEADER de segurança HTTP(Authorization:Basic) o
usuario e senha.
Quatro tipos de Autenticação
FORM - transmite os dados sem nenhuma segurança, permite customização tela de login, Espec. J2EE ,
Integridade dos dados muito fraca.
BASIC - transmite os dados de forma codificada na base64(não criptografada), Espec. HTTP , Integridade
dos dados fraca.
DIGEST - transmite os dados de forma criptografada, os containers J2EE não são obrigados a suportar,
Espec. HTTP, Integridade dos dados mais forte.
CLIENT-CERT - transmite os dados de forma segura, usando certificados de chave pública. A
desvantagem é que os seus cliente precisam ter o certificado.
Espec. J2EE, Integridade dos dados forte (chave pública - Public Key Certificates(PKC)).
Configuração no DD, apenas um <login-config> é permitido no web.xml
<web-app>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
Destalhes do FORM
<web-app>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/loginPage.html</form-login-page>
<form-error-page>/loginError.html</form-error-page>
</form-login-config>
</login-config>
</web-app>
Três entradas no formulário de login é obrigatório j_security_check, j_username, j_password
Integridades dos dados : Os dados não podem ser modificados ao longo do caminho
Confidencialidade : Os dados não podem ser vistos ao longo do caminho
Funcionamento - O Browser realiza uma solicitação ao servidor, O Container vê que este recurso restrito
tem uma garantia de transporte e envia um 301, que diz ao browser para redirecionar a solicitação
usando transporte seguro, o browser faz a mesma solicitação novamente, mais agora o protocolo é
HTTPS. O container vê que o recurso é restrito e que o usuário não foi autenticado e envia uma 401 ao
browser, o Browser envia a solicitação pela terceira vez com os dados necessários.
Quando você diz a um container J2EE que deseja implementar Integridade e Confidencialidade dos
dados, a especificação garante que os dados a serem transmitido viajarão através de uma conexão de
camada de transporte protegida(não garantido mais quase todos usa SSL),é uma solicitação HTTPS
através do SSL.
Configuração no DD (É usando dentro do <security-constraint>)
<user-data-constraint>
<transport-garantee>CONFIDENTIAL</transport-garantee>//Outras opções é INTEGRAL e NONE(Padrão)
</user-data-constraint>
Capítulo 13 - Filtros
Os filtros residem no container e são semelhantes aos servlets, Os filtros têm sua própria API a interface
javax.servlet.Filter.
O container gerencia o ciclo de vida deles com os metodos init(), doFilter(), destroy(). Todos Filtros deve
implementar os três metodos da interface.
O init(FilterConfig config) é usado para salvar o objeto FilterConfig
O doFilter() recebe objetos ServletRequest, ServletResponse e javax.servlet.FilterChain
O destroy() é chamado quando o container decide remover a instância do Filtro.
O FilterChain sabe qual filtro ou servlet vem em seguida na cadeia declarada no DD, seu metodo
doFilter(ServletRequest req, ServletResponse resp ) se ocupa em descobrir qual filtro ou servlet invocar
em seguida diferente do doFilter() do servlet que realiza um filtragem. Se o container não puder
localizar o recurso correto para solicitação, o filtro nunca é invocado
Configuração no DD
<filter>
<filter-name>BeerRequest</filter-name>// Obrigatório
<filter-class>foo.BeerRequestFilter</filter-class>// Obrigatório
<init-param>// Opcional
<param-name>Log</param-name>
<param-value>log.txt</param-value>
</init-param>
</filter>
<filte-mapping>
<filter-name>BeerRequest</filter-name>// Obrigatório
<url-pattern>*.do</url-pattern>// Obrigatório haver um <url-pattern> ou um <servlet-name>
<dispatcher>REQUEST</dispatcher>// Opcional
<dispatcher>INCLUDE</dispatcher>// Opcional
<dispatcher>FORWARD</dispatcher>// Opcional
<dispatcher>ERRO</dispatcher>// Opcional
</filte-mapping>
Importante: Todos os filtros com padrões de URLs <url-pattern> são localizados primeiros por ordem
declaradas no DD, depois é feito o mesmo para o <servlet-name>
Importante: O <filte-mapping> pode ter tanto <url-pattern> quanto <servlet-name>, <servlet-
mapping> pode ter apenas <url-pattern>.
Quandos passamos um ServletResponse para um servlet este escreve a resposta e devolve para o
cliente e não para o filtro que o chamou, se quisermos acessar a resposta devemos passar objetos
falsosm personalizados para o servlet assim ficamos com os objetos verdadeiros impedindo do servlet
devolver a resposta.Esse objeto falso precisa ser algo do tipo SevletResponse, temos os Wrappers para
resolver nosso problema, ele embrulhar o objeto verdadeiro, temos 4 deles.
ServletRequestWrapper
HttpServletRequestWrapper
ServletResponsetWrapper
HttpServletResponseWrapper
Os Wrappers são exemplos de padrões de projetos conhecido como Decorator
Capítulo 14 - Padrões de Design Enterprise
Um padrão de projetos em software é uma solução reutilizável para um problema de ocrrência
frequente em um software.
Camada Web : Contém paginas HTML, JSPs, Servlet , controladores , componentes de modelo
(Depende) , etc
Camada Negocio - Contém EJBs etc.
Pressões Comum
Requerimento funcionais : geralmente são interações com o usuário.
Requerimento Não funcionais : são coisas que acontece nos bastidores. Ex:
1-)Desempenho,
2-)Modularidade(partes do software podem rodar em diferente JVM) e
3-)Flexibilidade(Manutenção simples), Gerenciabilidade , Extensibilidade(Incluir novos recursos de
maneira simples).
Princípios de projetos de software
Código para interfaces : Interface é um contrado entre dois objetos e gera o polimorfismo.
Separação de Objetivos e coesão : Separar os objetivos a coesão tende a aumentar,usado para
satisfazer a Flexibilidade e Gerenciabilidade Ex:ServiceLocator
Esconder a Complexibilidade : Criar componentes especializados, anda de mão juntas com a (Separação
de Objetivos e coesão).
União soltas : Reduzir o acoplamento, Quando menos as duas classes souber sobre a outra mais solta é
a união entre elas.
Proxy Remoto(Stub) : É um objeto local que finge ser um objeto remoto, este objeto se encarrega de
todas complexibilidade para ser comunicar com objeto real.
Maior Controle Declarativo : É implementado usando o Deployment Descriptor DD.
Definições de JNDI e RMI
JNDI : Java Naming and Directory Interface(Interface Java de Nomeação de Diretórios). A JDNI dá a rede
uma localização de onde encontrar as coisas, você registrar os seus objetos com a JNDIe outros
programas podem acha-los.
RMI : Remote Method Invocation(Invocação de Métodos remotos). Um mecanismo que simplifica o
processo de dois objetos se comunicarem através da rede,Um objeto em uma JVM invoca um método
em um outro objeto que está em outra JVM, mais fingindo que está invocando um objeto local.O RMI
usa o proxy Remoto. No RMI é criado um "Stub" no cliente e um "esqueleto" no servidor , (O stub acessa
o esqueleto e o esqueleto acessar o objeto real).
Padrões de Projetos
Business Delegate : é um objeto intermdiário para encapsular o acesso a um serviço de negócio, ele
diminuir o aclopamento entre o controlador e o serviços de negocios assim escondendo os detalhes de
implementação tais como pesquisa e acesso.
Princípios: Esconde a complexibilidade, programar para interfaces, união solta, separação dos objetivos.
Ex: se você for chamar um metodo buscarClientes(), e para não colocar método no Servlet com a logica
de buscar um objeto local ou remoto, você cria esse objeto intermediário que usa JNDI com RMI para
acessar os dados. para o Servlet não importa se o buscarClientes() é um metodo local ou remoto.
ServiceLocator : é um objeto localizador que encapsular o acesso a serviçõs de pesquisa de
componentes, esconde os detalhes de implementação de busca do JNDI.
Princípios : Esconder a complexidade, separação dos objetivos , reduz a união entre as camadas.
Obs: Use o ServiceLocator com Business Delegate para não ter código duplicado de pesquisa de registro
de nomes no Business Delegate,assim a obtenção do stub é feita pelo ServiceLocator e tudo que o
Delegate tem que fazer é lidar com os metodos de negócios no stub. Aumenta a coesão do Business
Delegate.
Transfer Object : pode ser um Java Bean carregado com valores, é implementado como um objeto
serializável. Uma desvangem é que os dados ficam desatualizados.
Principios : reduzir o tráfego na rede.
Intercepting Filter : Use para modificar solicitações e respostas, Os filtros são um exemplo de
Intercepting Filter. Está mais ligado ao Front Controller
Princípios : Coesão , União solta, Maior Controle Declarativo.
MVC : São divididos em (Modelo , View e Controlador)
Princípios : Separação dos objetivos e uniões soltas.
Front Controller : Usado para juntar códigos em comum , geralmente junto com o padrão MVC, que
introduz o conceito de um controlador único, usa bastante controle declarativo, permite um controlador
mais coeso e menos complexo.
Princípios : esconder a complexidade, separação dos objetivos e união solta.