Busca

What's up

Webblog in construction

Categoria

Java

Ordenando dados em uma tabela

Pois é, depois de muito … mas muito tempo volto a escrever alguma coisa aqui. Manter um blog requer tempo ! Mas … enfim … vamos levando na medida do possível.

Estive pesquisando formas de fazer ordenação de colunas na tabela, minha idéia era utilizar javascript para fazer o negócio bem dinâmico e que deixasse o servidor livre, nada de Ajax, fazer uma coisa simples mesmo. Então fiz uns testes com a biblioteca JQuery.

JQuery é uma biblioteca javascript que possui diversas funções e efeitos visuais para tornar nossas interfaces mais “rica”. Além de ser uma biblioteca pequena e as funções javascripts são compatível com diversos tipos de browsers.

Para ordenar os dados de uma tabela com JQuery utilizei o plugin TableSorter. Ele faz a ordenação de dados de uma tabela via javascript e é muito simples de usar.

Para iniciar o uso, basta adicionar os .js ao seu projeto.
<script type="text/javascript" src="/path/to/jquery-latest.js"></script>
<script type="text/javascript" src="/path/to/jquery.tablesorter.js"></script>

Na sua tabela vc vai adicionar as tags <THEAD> e <TBODY>
<table id="idDaTabela">
<thead>
<tr>
<th>Nome</th>
<th>Endereço</th>
<th>Email</th>
</tr>

</thead>
<tbody>
<tr>
<td>João</td>
<td>R. um casa 5</td>
<td>joao@gmail.com</td>
</tr>
<tr>
<td>Marcos</td>
<td>Av. 7 de setembro, 258</td>
<td>marcos@yahoo.com</td>
</tr>
<tr>
<td>Carla</td>
<td>R. quatro, 50</td>
<td>carla@hotmail.com</td>
</tr>

</tbody>
</table>

Note que a celulas dos cabeçalho da tabela tem que está entre as tags <TH>. Se vc utilizar <TD> ele não reconhece como cabeçalho da tabela mesmo estando entre as tagas <THEAD>.

Pode ser bloqueada a ordenação de uma ou mais colunas da tabela. Para isso faça:

<th ... class="{sorter: false}>

Para chamar utilizar a API :

< script>
$(document).ready(function() {
$("#idDaTabela")
.tablesorter( {sortList: [[0,0], [1,0]]} )
} );
</script>

No script acima, estou chamado a plugin tablesorter e ordenando a coluna 0 e 1 de forma ascesdente. Assim toda vez que a pagina for carregada já trás as colunas 0 e 1 da tabela ordenadas.

Para melhorar a vizualização da ordenação pode ser configurado CSS.

th.header {
background-image:url(../img/green_arrows.gif);
font-weight: bold;
background-repeat: no-repeat;
background-position: center left;
padding-left: 20px;
border-right: 1px solid #dad9c7;
margin-left: -1px;
background-color: #D1E6ED;
....
}

Configura o head da tabela, observe que tem uma imagem que serve para informa ao usuário qual ordenaçao deseja fazer.

th.headerSortUp {
background-image:url(../img/green_acending.gif);
background-color: #B0C4DE;
}

th.headerSortDown {
background-image:url(../img/green_decending.gif);
background-color: #B0C4DE;
}

Na pagina os plugin tablesorter tem mais exemplos e uma documentação bem legal.

Ahhh o JQuery tbm tem um plugin para paginação jquery.tablesorter.pager.js.

Mas para esse post vou encerrando por aqui.

Att.

Referências

http://tablesorter.com

Filters

Chapter 13

PS. Este é um resumo para prova SCWCD

Filtros são componentes utilizados para interceptar um resquest antes de chegar ao servlet ou interceptar um response antes de chegar ao cliente. O container decide a ordem para invocar o filtro baseado na ordem da declaração no DD.

Um filtro deve implementar a interface javax.servlet.Filter

Em exemplo de filtro

package minhasClasses.filtros;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.*;

public class MeuFiltro implements Filter{

private FilterConfig filterConfig;

//tem que implementar esse metodo

public void init(FilterConfig config) throws ServletException{
this.filterConfig = config;
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException{
// o que o filtro vai fazer
chain.doFilter(req, resp);
}
public void destroy(){
// tem que implementar esse metodo. Lembre-se ... a interface.
}
}

Mapeando um filtro no DD

<filter>
<filter-name>meuFiltro</filter-name>
<filter-class> minhasClasses.filtros. MeuFiltro</filter-class>

<init-param>
<param-name>param1</param-name>
<param-value>algumaCoisa</param-value>
</init-param>
</filter>

Mapeando um filtro para uma url

<filter-mapping>
<filter-name>meuFiltro</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>

Mapeando um filtro para um servlet

<filter-mapping>
<filter-name>meuFiltro</filter-name>
<servlet-name>meuServlet</servlet-name>
</filter-mapping>

Um filtro também pode funcionar em caso como dispatcher, include, forward ou erro, mas deve ser colocado no DD

<filter-mapping>
<filter-name>meuFiltro</filter-name>
<url-pattern>*.do</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

<dispatcher> também pode ser INCLUDE, FORWARD ou ERROR. Caso não tenha declarado o <dispatcher> o default é REQUEST.

Web app security

Chapter 12
PS. Este é um resumo para prova SCWCD

Os principais conceitos de segurança são: autenticação, autorização, confidencialidade e integridade.

Autenticação
Saber se a pessoa que está utilizando a aplicação é ela mesma. Isso é feito através de login e senha.

No DD

<security-role>
<role-name>Admin</role-name>
<role-name>usuario</role-name>
<role-name>visitante</role-name>
</security-role>

Autorização
Depois de autenticado saber quais os acessos permitidos ou autorizado.

<web-app ...>
<security-constraint>
<!-- pode haver mais de um elemento web-resource-collection -->

<web-resource-collection>
<web-resource-name>moduloUsuario</web-resource_name>
<!-- defino quais os recurso estão seguros -->
<!-- url-pattern é obrigatório ter pelo menos uma -->

<url-pattern>/usuario/cadastro/*</url-pattern>
<url-pattern> … </irl-pattern>
<!-- http-method é opcional -->
<!-- se nenhum http-method é declarado significa que todos os metodos serão protegidos -->

<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<!-- se aplica a todos os resource-collection no mesmo security-constraint -->

<auth-contraint>
<role-name>usuario</role-name>
</security-constraint>
</wep-app>


<auth-constraint>

Atenção para:
1 – Se
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>

Então todos tem acesso.

2 -Caso nenhum elemento <auth-constraint> no DD, então todos tem acesso.

3 – Se
<auth-constraint/>
então ninguém tem acesso.

Métodos associado com segurança

isUserInRole()
Antes de usar esse método o usuário precisa está autenticado. Caso ainda não esteja autenticado o container sempre retornará falso.

getUserPrincipal()

esse método é mais usado com EJB

getRemoteUser()

para pegar o status da autenticação.

Esse métodos estão em HttpServletRequest

Tipos de autenticação

Tem 4 tipos de autenticação

BASIC – as informações de login são transmitidas encoded (só conheço assim “encoded” tem uma tradução apropriada ?) , voltando… , encoded no schema base64.
Ex:
<web-app ...>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>

</web-app>

DIGEST – Transmiti as informações de login de forma mais segura, porque tem mecanismos de criptografia.
Ex:
<web-app ...>
<login-config>
<auth-method>DIGEST</auth-method>
</login-config>

</web-app>

CLIENT-CERT – é estremamente seguro, usa certificação de chave publica. Esse tipo de autenticação é muito usado em b2b.
Ex:
<web-app ...>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>

</web-app>

Esse três as informações de login são digitas em pop-up form.

FORM
– Aqui vc pode criar seu próprio formulário para input dos dados.
<web-app ...>
<login-config>
<auth-method>FORM</auth-method>
<form-login-confirm>
<form-login-page>/login.html</form-login-page>
<form-error-page>/loginError.html</form-error-page>

</form-login-confirm>
</login-config>
</web-app>

O form login deverá ser da seguinte forma:

<form method="POST" action="j_security_check">
<input type="text" name="j_username">
<input type="password" name="j_password">
<input type="submit" value="enter">
</form>


Configurante integridade e confiabilidade


<web-app ...>
<security-constraint>
<web-resource-collection>
<web-resource-name>moduloUsuario</web-resource_name>
<url-pattern>/usuario/cadastro/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-contraint>
<role-name>usuario</role-name>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>

</security-constraint>
</wep-app>

Em <transport-guarantee> pode ter os valores:

NONE
É o default, significa não tem proteção

INTEGRAL
Os dados não poderão ser alterados

CONFIDENTIAL

Os dados não podem ser visto pode ninguém.

Custom tags (parte II)

Chapter 9
PS. Este é um resumo para prova SCWCD

Utilizando nossas próprias tag

Seguindo a sequencia do livro, agora vai ser falado sobre utilização das nossas próprias tags.

Toda tag customizada é declarada no arquivo .tld. E é a partir das informações contidas neste arquivo que vamos utilizar a tag no JSP.

No arquivo tld:

<taglib ...>
...
<uri>minhaTagUri<uri>
<tag>
<description> Aqui é a descrição da tag, este elemento é opcional, mas é uma boa prática a sua utilização </description>
<name>nomeTag</name>
<tag-class>minhasClasses.MinhaTag</tag-class>
<body-content>empty</body-content> <!-- o valor default é JSP -->
<attribute>
<name>atributo</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>

Algumas notas:

Em <rtexprvalue>true</rtexprvalue>, significa que aceita run time expression value. Caso não seja mencionado o default é falso. Quando <rtexprvalue>false</rtexprvalue> o atributo só aceitará strings.

No elemento <body-content> pode ter os seguintes valores:

<body-content>empty</body-content>

Quando a tag não tem corpo

<body-content>scriptless</body-content>
A tag NÃO pode ter scripts como: scriptless, scripting expression ou declaration MAS pode ter text, EL, standard e custom actions.

<body-content>tagdependent</body-content>
Todo o conteúdo do corpo da tag é tratado como texto.

<body-content>JSP</body-content>

No corpo pode conter qualquer coisa que possa ter em um JSP.

No arquivo JSP:

<html>
<body>
<%@ taglib prefix="bla" uri="minhaTagUri" %>
Agora posso utilizar a tag
<bla:nomeTag atributo="${algumaCoisa}" />
</body>
</html>

Agora vamos à classe que implementa a tag.Note: Uma simple tag extende de SimpleTagSupport

package minhasClasses;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;

public class MinhaTag extends SimpleTagSupport{

private String atributo;


// Esse método será chamado pelo container quando a tag for executada no JSP
public void doTag() throws JspException, IOException{
getJspContext().getOut().write("Minha tag");
}


public void setAtributo(String atributo){
this.atributo = atributo;
}
}

Com <jsp:attribute> podemos passar o atributo da tag.

<html>
<body>
<%@ taglib prefix="bla" uri=" minhaTagUri" %>
Agora posso utilizar a tag
<bla:nomeTag>
<jsp:atributte name="atributo">${algumaCoisa}</jsp:atributte>
</bla:nomeTag>
</body>
</html>

Aonde colocar a arquivos TLDs ?

O container procura os arquivos TLD dentro do diretório WEB-INF, dentro de seus subdiretórios, dentro da pasta META-INF dentro dos JARs e dentro dos subdiretórios do META-INF.

NOTA: Quando for usar mais de uma tag lib, deve-se tomar cuidado, os valores da uri devem ser únicos. Tomar cuidado com os prefixos reservados:
jsp:
jspx:
java:
javax:
servlet:
sun:
sunw:

Custom tags (parte I)

Chapter 9
PS. Este é um resumo para prova SCWCD

Usando JSTL


<c:forEach>

Para iterar sobre array e collection

<c:forEach var="cliente" itens="${clientes}">
${cliente}
</c:forEach>

Podemos especificar também uma variavel para receber o valor do contador do for

<c:forEach var="cliente" itens="${clientes}" varStatus="loopCount">
Cont: ${loopCount.count} <br>
${cliente}
</c:forEach>

Com c:forEach tem os atributos opcionais begin, end e step.

<c:if>

Nem precisa falar para que server ! Vamos ao exemplo:

<c:if test="${cliente eq 'Master'}">
// corpo do if
</c:if>

Note: a tag <c:if> não possui else.

<c:choose>
Vc pode testar várias condições e utilizar o “else”
Ex:
<c:choose>
<c:when test="${cliente eq 'Master'}">
Este cliente é master
</c:when>
<c:when test="${cliente eq 'Simple'}">
Este cliente é simple
</c:when>
<c:otherwise>
Este cliente não é master e nem simple.
</c:otherwise>
</c:choose>

<c:set>

Atenção : com <jsp:setProperty> pode ser setado apenas as propriedades de um bean. Para setar valor de um Map, colocar um novo valor Map, criar um novo atributo no request-scope tem que ser usado a tag <c:set>

Ex:
<c:set var="cliente" scope="session" value="${cliente}"/>

Caso não exista um atributo cliente na session, será criado no novo.

Com c:set também pode ser setado o valor de um map ou bean

<c:set target="${Clientes}" property="cliente" value="Marcio" />

Onde:
target – não pode ser null
property – se target for map o valor de property será a chave no mapa

dá mesma forma podemos dizer

<c:set target="${clientes}" property="cliente" > Marcio </c:set>

Atenção a propriedade target sempre dá referencia a um objeto.

Pontos para lembrar:
– O escopo default para para c:set é page
– Se o valor do atributo chamado por var for null, esse atributo será removido. E se o for setado um objeto com target e o valor for null o container vai lançar uma exceção.
– O nome passado para o atributo target tem que ser um map ou bean, caso contrário será lançado uma exceção.

Novamente: com c:set só remove alguma coisa quando é passado um valor null para o property.

Uma forma mais intuitiva para remover algo é utilizar <c:remove>
<c:remove var="clientes" scope="session" />

Ao caso não seja mencionado o scope o default é page.

Outra forma de incluir um conteúdo

Assim como <jsp:include ... > temos o <c:import ...> que incluído o conteúdo de forma dinâmica. Porém, com <c:import ...> o conteúdo pode está fora do container.
<c:import url=http://www.conteudoparapagina.com/exemplos.html />

Também pode ser usado <jsp:param> com o <c:import>

<c:import url="cabecalho.jsp">
<c:param name="clienteNome" value="Jorge Matos" />
</c:import>

No arquivo cabeçalho.jsp

Cliente nome: ${param.clienteNome}

<c:url>
Como o <c:url> podemos resolver casos aonde os JSPs não aceitam cookies

<a href="<c:url value="/home.jsp" var="valorUrl">" >link </a>

Note: o atributo var é opcional e é usado para ver o valor do link.

Importante saber: os parâmetros passados dentro do <c:url> é encoding.

Error Pages

Com errorPage podemos dizer ao container, caso ocorra algum erro direcionar para a pagina
<%@ page errorPage="errorPage.jsp" %>

No arquivo errorPage.jsp deve ter a tag
<%@ page isErrorPage="true" %>

Importante: Quando o JSP é ErrorPage ele tem um objeto implícito exception. Com esse objeto é possível imprimir o erro na pagina.

<%@ page isErrorPage="true" %>
<html>
<body>
O erro ocorrido foi: ${pageContext.exception}

</body>
</html>

No DD podemos configurar paginas de erros para diferentes erros.

<!-Declara um error page para um tipo de erro '
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/errorPage.jsp</location>
</error-page>

<!-Declara um error page de acordo com um status '
<error-page>
<error-code>java.lang.Throwable</error-code>
<location>/errorPage.jsp</location>
</error-page>

Caso um erro possa ser tratado por mais de um elemento error-page o mais restrito será executado.

Trando erros no JSP

<%@taglib prefix="c" uri="http://java.sun.com/jsp/core" %>
<%@ page errorPage="errorPage.jsp" %>
<html>
<body>

<c:catch var="e">
<% int a = 30%0; %>
</c:catch>

<c:if test="${e != null}">
O erro ocorrido foi: ${e.message}
</c:if>
</body>
</html>

A variavel criada em <c:catch var="e"> terá escopo page.

Script-free pages (parte II)

Chapter 8
PS. Este é um resumo para prova SCWCD

Continuando…

Directiva Include

No arquivo cabecalho.jsp

<html><body>
Essa pagina tem meu cabeçalho
</body></html>

E neste JSP eu quero incluir o JSP do cabeçalho

<html><body>
<%@ include file=""cabecalho.jsp" %>
<br>
Minha pagia
</body></html>

<jsp:include> Standard action

<html><body>
<jsp:include page="cabeçalho.jsp"/>
<br>
Minha pagia
</body></html>

Atenção : A directiva include inseri o código do JSP em tempo de tradução enquanto o standard action inseri o conteúdo do JSP em tempo de execução.

Com a directiva o container vai “ter o trabalho” de montar a pagina apenas uma vez, no primeiro request. No caso do tomcat, a especificação garante que quando for alterado o JSP do include “esse trabalho” será feito novamente, mas nem todos os container oferece essa garantia. Como o standard action “esse trabalho” vai ocorrer a cada request.

Lembre-se:
Os atributos das directivas são diferentes:
<%@ include file=""cabecalho.jsp" %>
<jsp:include page="cabeçalho.jsp"/>

Dica:
Para JSP que serão reutilizados não deve ser colocado tags de abre e fecha <html> e <body> para não ocorrer casos como:
<html><body>
<html><body></body></html>
</body></html>

Customizando o conteúdo incluído

<html><body>
<jsp:include page="cabeçalho.jsp">
<jsp:param name="tipoUsuario" value="Visitante" />
</jsp:include>
<br>
Minha pagina
</body></html>

Então no cabeçalho eu poderia pegar o valor do parâmetro:

<html><body>
Essa pagina é meu cabeçalho <br>
Eu sou um usuário do tipo : ${param.tipoUsuario}
</body></html>

Caso já exista um paramentro com o mesmo nome o valor setado em jsp:param será sobrescrito no parametro já existente.

Assim como o standard action include, podemos tbm fazer um forward.

<jsp:forward page="paginaForward.jsp" />

Quando tem a jsp:forward o buffer do response é limpo, então qualquer coisa que vc escrever antes não aparecerá na pagina.
Com jsp:forward o request é “direcionado” para qualquer recurso na mesma aplicação.

Script-free pages (parte I)

Chapter 8
PS. Este é um resumo para prova SCWCD

Como a idéia agora é nada de script nos JSP. Então vamos ao que interessa:

Um exemplo bem comum … temos um servlet que tem um bean que vai ser passado para o JSP como atributo do request e esse bean vai ser usado para carregar o JSP.

<html>
<body>
<jsp:useBean id="dog" class="minhasClasses.Dog" scope="request"/>
O nome do cachorro: <jsp:getProperty name="dog" property="nome"/>
</body>
</html>

O atributo id do standard action jsp:useBean, é o nome do atributo que está no request. O atributo class declara o tipo da classe do bean.
No standard action jsp:getProperty, o atributo name é o nome do atributo = id no jsp:useBean. No property coloca-se o nome do atributo do bean.

O standard action jsp:useBean procura no escopo informado o atributo, caso não encontre ele irá criar um atributo. Então utilizando jsp:setProperty pode ser setado no jsp os atributos do bean.

<jsp:useBean id="dog" class="minhasClasses.Dog" scope="request"/>
<jsp:setProperty name="dog" property="nome" value="pluto" />

OBSERVAÇÃO: no exemplo acima será setado o valor do property, caso tenha ou não encontrado o atributo. Para setar o atributo apenas quando for criado um novo segue abaixo:

<jsp:useBean id="dog" class="minhasClasses.Dog" scope="request">
<jsp:setProperty name="dog" property="nome" value="pluto" />
<jsp:useBean>


Utilizando polimorfismo

Com o jsp:useBean pode também utilizar polimorfismo. Ex:

Package minhasClasses;
public abstract class Animal{
private String nome;
public void setNome(String nome){
this.nome = nome;
}
Public String getNome(){
return this.nome;
}
}

e

package minhasClasses;
public class Cachorro extends Animal{
private String raca;
public void setRaca(String raca){
this.raca = raca;
}
public String getRaca(){
return this.raca;
}
}

No jsp fica:

<jsp:useBean id="animal" type="minhasClasses.Animal" class="minhasClasses.Cachorro" scope="page">

No servlet gerado por este JSP:

minhasClasses.Animal animal = null;
// aqui pega o atributo
if(animal == null){
animal = new minhasClasses.Cachorro();
}

No atributo type pode ser tanto uma classe abstrata como uma interface. No atributo class deve ser sempre uma classe concreta que implemente ou extende da classe type, ou a exceção java.lang.InstatiationException será lançada caso não encontre o atributo na sessão.

Também pode ser usado a tag sem o atributo class, mas isso só irá funcionar caso já exista o atributo no escopo.

LEMBRE-SE
Type = pode ser classes abstrata ou interface
Class = tem que ser classes concreta

O atributo scope é opcional, o default é page.

Atenção ! Para as questões onde o atributo é setado no request e no JSP a tag jsp:useBean está sem o scopo. Por neste caso, o jsp estará tentando pegar o atributo no escopo page.

Setando atributos de um bean com parametros

<jsp:useBean id="cachorro" type="minhasClasses.Cachorro">
<jsp:setProperty name="cachorro" property="nome" param="nomeCachorro"/>
</jsp:useBean>

Nota: se o paramentro for passado com o mesmo nome do atributo do bean não é necessário passar o param no standard action jsp:setProperty.

Nota: Para beans que tenham atributos tipos diferentes de String a conversão é automática, desde que seja um tipo primitivo. Agora, cuidado ! Os valores tem que ser valores válidos, por exemplo caso tenha um campo int, crie validação ou algo que garanta que o valor do parâmetro passado ao JSP seja um int.

Para setar vários atributos de um bean:

<jsp:useBean id="cachorro" type="minhasClasses.Cachorro">
<jsp:setProperty name="cachorro" property="*"/>
</jsp:useBean>

Agora vamos supor … a classe cachorro da seguinte maneira:

public class Cachorro{
private int id;
private String nome;
private Pessoa dono;
// gets e sets ...
}

E a classe pessoa

public class Pessoa{
private int id;
private String nome;
// gets e sets …
}

No JSP quero mostrar o nome do dono do cachorro.

Com EL
<html>
<body>
O dono do cachorro se chama : ${cachorro.dono.nome}
</body>
</html>

Em EL
${primeiraCoisa.segundaCoisa}

primeiraCoisa pode sempre ser objetos implícitos ou atributos

RELEMBRANDO !
Objetos implícitos:
pageScope
requestScope
sessionScope
applicationScope

param
paramValues

header
headerValues

cookie

initParam

Com o (.) pode ser acessar propridades de um bean e valores de um map, mas com [] pode acessar valores de todos estes e mais array ou list.

${cachorroList[0]} ou ${cachorroList["0"]}

Atenção: O objeto ímplicito requestScope é apenas um Map com os atributos do request, muiiiito cuidado para não confundi-lo com objeto request. Para acessar os
atributos do objeto request use, por exemplo:

${pageContext.request.method}

Escopo em implícitos objetos

Caso tenha um objeto, exemplo cachorro em um escopo e vc sabe que esse objeto só poderá está em um escopo
${cachorro.nome}

Dessa forma o atributo cachorro pode está em qualquer um dos atributos. Agora, caso queira pegar o atributo em escopo definido
${requestScope.cachorro.nome}

Com EL podemos pegar cookies

${cookie.userName.value}

Executando métodos java no JSP através de taglib

1 – Tenho uma classe que tem o método que vai ser executado. Esse método tem que ser publico e estático. Como vamos ver mais abaixo, essa classe vai ser configurada em um arquivo TLD e então, para essa classe ser encontrada ela deve está dentro da pasta ou subpastas de WEB-INF/classes, isso compilada, o arquivo .class.

Package minhasClasses;
public class MinhaClasse{
public static String metodoJSP(){
return ("Executou o método");
}
}

2 – O arquivo TLD Tag Library Descriptor

Esse arquivo provê o mapeamento entre a classe java e a função que será chamada no JSP. Ele tem que ser salvo na extensão .tld e deve ficar sempre na pasta ou subpasta dentro de WEB-INF. Então vamos ao arquivo

<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib ...>
<tlib-version>1.2</tlib-version>
<uri>minhaFuncao</uri>
<function>
<name>funcao</name>
<function-class>minhasClasses.MinhaClasse</function-class>
<function-signature>
String metodoJSP()
</function-signature>
</function>
</taglib>

3 – Enfim, chamando no JSP

<%@ taglib prefix="minha" uri="minhaFuncao" %>

<html><body>
${minha:funcao()}
</body></html>

Atenção : O nome chamado do método no JSP é mapeado no arquivo .tld. Note que ele pode ser diferente do nome do método na classe java


Operadores com EL

Com EL pode ser usados os operadores
Aritméticos:
+, -, *, / ou div, % ou mod

Lógicos:
&& ou and, || ou or, ! ou not

Relacionais
== ou eq, != ou ne, < ou lt, > ou gt, <= le, >= ou ge

Lembre-se : Com / ou div pode haver divisão por zero o resultado vai ser infinito e NÃO UM ERRO. Com % ou mod não pode pegar o resto da divisão por zero senão VAI DAR UM ERRO.

EL is null-friendly

EL “se dá bem” com valores null.

Supondo o atributo x nulo. Caso tenha no JSP ${x} não vai imprimir nada e não aparece erro. Valores nulos tbm pode ser utulizado com os operadores.
Ex
${7 > x} //resultado TRUE
${x == x} // resultado TRUE
${true and x} // resultado FALSE

Exceção: apenas o operador % não é null-friendly.

${100 % x}//resultado lança uma exceção

JSP

Chapter 6
PS. Este é um resumo para prova SCWCD

Em uma aplicação, os JSPs rodam como servlets. Quando um JSP é escrito, o container o converte para um servlet em um arquivo .java, compila para um arquivo .class e aqui ele vai poder ser instanciado e inicializado.

Directive Page
Directivas são formas de vc dar uma instrução para o container. Uma directiva pode ser: page, include ou taglib. A directiva é iniciada com <%@, então a partir daí o container saber que se trata de uma directiva.

Utilizando a directiva page

<%@ page import="minhasClasses.*" %>
<html>
<body>
...
</body>
</html>

Para fazer o import de várias classes vc pode usar a (,).

<%@ page import="minhasClasses.*, java.util.*" %>

Expressions
Com expressions é posssível simplificar o código JSP.

Ex:
<%@ page import="minhasClasses.Dog" %>
<html>
<body>
<% out.print(Dog.getCount()); %>
</body>
</html>

Com expressions

<%@ page import="minhasClasses.Dog" %>
<html>
<body>
<%=Dog.getCount() %>
</body>
</html>

Tudo que estiver na expression será passado como parâmetro para o comando out.print(), isso quando o container for traduzir o JSP para arquivo .java. Então NÃO SE COLOCA (;) NO FINAL DO COMANDO.

LEMBRE-SE Em uma expressão nunca terá (;)

Declarations

Tudo que estiver em um scripteless no JSP é traduzido no método service do JSP, então variáveis serão sempre variáveis locais. Para podermos ter variáveis de instância utilizamos declarations.

<%! int count=0; %>
Aqui, count é uma variável de instancia.
Com declarations também é possível declarar métodos que serão estáticos.

Implicit Object
Objetos implícitos faz o mapeamento do JSP para servlet.
Ex:
O objeto implícito request, referencia o objeto HttpServletResquest.
Abaixo segue alguns:

Objetos Implícitos = API

out = JSPWriter
request = HttpServletRequest
response = HttpServletResponse
session = HttpSession
application = ServletContext
config = ServletConfig
exception = JSPException
pageContext = PageContext
page = Object

O objeto implícito exception só estará habilitado caso o JSP tenha a directiva
<%@ page isErrorPage="true" %>, caso contrário o objeto será null.

Inicialização do JSP

Configurando os paramentros de inicialização do JSP.

<web-app ...>
...
<servlet>
<servlet-name>JspComParamentros</servlet-name>
<jsp-file>/JspComParametros.jsp</jsp-file>
<init-param>
<param-name>parametrosTeste</param-name>
<param-value>teste</param-value>
</init-param>
</servlet>
...
</web-app>

Assim como no servlet, os parâmetros de inicialização serão carregados na inicialização do JSP, no método jspInit().

No JSP os atributos podem ficam em 4 escopos diferentes: request, session, application (context) e ainda page.

Setando o atributo no JSP usando implícitos objetos:

application.setAttribute("dog", dog);
request.setAttribute("dog", dog);
session.setAttribute("dog", dog);
page.setAttribute("dog", dog);

Através do objeto implícito pageContext vc pode pegar os atributos de qualquer escopo, utilizando o método getAttribute(String name, intScope) na classe PageContext tem variáveis static final para cada escopo, então

<%= pageContext.getAttribute("dog", PageContext.SESSION_SCOPE) %>

Para pegar o atributo na sessão. Assim como getAttribute tbm tem o setAttribute que pode setar atributos em qualquer escopo.
Segue as variáveis da classe PageContext

APPLICATION_SCOPE
PAGE_SCOPE
REQUEST_SCOPE
SESSION_SCOPE

O método findAttribute(String name) procura o atributos em todos os escopos, qual achar primeiro será retornado. Ele começa a procurar do escopo mais restrito.

ATENÇÃO:
O método pageContext.getAttribute(String name) pegar o attributo que está no escopo page.

Expression Language

Código java em JSP é difícil de alterar e manter. Isso é fato! Então para resolver esse e outros problemas utilizamos expression language.
Usando expressão java
Email: <%= application.getAttribute("email") %>

Com EL
Email ${applicationScope.email}

Para garantir que não terá scripts no JSP, poder ser configurado no DD para não permitir uso de scripts nos JSP.

<web-app ...>
...
<jsp-config>
<jsp-property-group>
<url-pattern> *.jsp</url-pattern>
<scripting-invalid> true </script-invalid>
</jsp-property-group>
</jsp-config>
...
</web-app>

No DD pode também ignorar EL

<web-app ...>
...
<jsp-config>
<jsp-property-group>
<url-pattern> *.jsp</url-pattern>
<el-ignored> true </el-ignored>
</jsp-property-group>
</jsp-config>
...
</web-app>

Ou pode ignorar EL via directiva
<%@ page isELIgnored="true" %>

LEMBRE-SE: Na directiva o atributo começa com “is“.

Session

Chapter 6
PS. Este é um resumo para prova SCWCD

Na prática, a comunicação entre cliente e servidor se dá com apenas request/response. Para cada requisição do cliente um novo objeto request é enviado ao servidor, mas para cada cliente vai existir apenas uma sessão.

Cada sessão tem um id que a torna única. No primeiro request da sessão o container seta o id da sessão com um valor que é retornado ao cliente no response. E a cada request subseqüente o valor do id da sessão é retornado ao servidor. Essa troca de id se dá utilizando cookies.

Para pegar uma sessão

HttpSession session = request.getSession();

Uma sessão pode ser pega através do objeto request ou em um lister através do objeto HttpSessionEvent.

Ao chamar o método getSession() o container poderá criar uma session caso ainda não tenha ou poderá retorna uma session já existente. Para saber se o session foi criada ou retornada uma já existente, podemos utilizar :

If(session.isNew()){
out.println("Essa é uma nova sessão");
}else{
out.println("Bem vindo novamente");
}

Também temos o método getSession(boolean) que pode resolver casos aonde não queremos criar uma nova sessão apenas utilizar as já existente

HttpSession session = request.getSession(false);
If(session==null){
// aqui não existe sessão para o request
} else{
//já existia sessão para o request
}

Para utilizar sessions o browser do usuário tem que está habilitado para trabalhar com cookies. Caso não esteja, o método encodeURL(), poderá resolver esses problemas.

response.encodeURL("/teste.do")

No método acima vai ser incluído id da session no final da url, mas apenas nos casos aonde o browser estiver com cookies desabilitados, fora isso o id da sessão será tratado da maneira “tradicional” .

O encode tbm trabalha com redirect

response.encodeRedirectURL("/teste.do");

No método encode a id da session aparece no request como uma informação extra, então qualquer tentativa de acessar o id da sessão como se fosse um parâmetro não irá funcionar!

Algums métodos HttpSession

Algums métodos que podem nos ajudar a manipular sessões:

getCreationTime()
getLastAccessedTime()
setMaxInactiveInterval()
getMaxInactiveInterval()
invalidate()

esses acho que nem precisa explicar.

Setando o timeout da sessão

Pode ser :
1- configurando do DD
<web-app .... >
<servlet>
...
</servlet>
<session-config>
<!-tempo passado em minutos -->
<session-timeout>15</session-timeout>
</session-config>
</web-app>

2- Setando no código o timeout
Session.setMaxInactiveInterval(15*60);
// o tempo passado em segudos

Depois que uma sessão ficar invalida vc não pode mais acessar os métodos da sessão ou a exceção IlegalStateException será lançada.

Cookies

Cookies além de ajudar o servidor identificar as sessões tbm serve para outros tipos de informação, par de string nome e valor. Ex. guardar o nome do usuário da sessão.
Cookies podem viver enquanto a sessão estiver ativa ou mesmo depois a sessão se ter sido encerrada.

Vamos ao código:

Cookie cookie = new Cookie("usuarioNome", "Maria");
// setando o tempo de vida, tempo em SEGUNDOS
Cookie.setMaxAge(30*60);
//colocando no reponse
Response.addCookie(cookie);

LEMBRE-SE
Não existe setCookie() apenas addCookie().

Setando o setMaxAge() para 0, a sessão será expirada de imediato, setando maxAge para -1 a sessão nunca será invalidada, mas isso só será valido para a sessão que o maxAge foi setado. Para que todas as sessões nunca expirem pode setar o maxAge via DD, neste caso, pode ser setado o timeout para 0 ou algum valor negativo.

<wep-app>
...
<session-config>
<session-timeout>0</session-timeout>
</session-config>
...
</web-app>

Em aplicações distribuídas vc pode ter um servletA em cada VM, um contexto por VM mas a sessão vc só vai ter uma por aplicação. Nestes caso a sessão é movida de uma VM para outra.

Blog no WordPress.com.

Acima ↑