Apostila
Java Web
www.3way.com.br
Java WEB
Sumário 1 1.1 1.2 1.2.1 1 .3 1 .4 1 .5 1 .6 1 .7 1 .8 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2 2 .1 2 .2 2 .3 2.3.1 2 . 3 .2 2 .3 .3
JDBC Banco de Dados Relacional JDBC – Java Database Connectivity java.sql.DriverManager Fábrica de Conexões Criar Banco de Dados e Tabelas Classes Javabeans – Entidades Inserindo Dados Fechando a Conexão PreparedStatement ou Statement Design Patterns DAO – Data Access Object Pesquisando Recurso avaçando: O Cursor Alteração Exclusão Introdução a Java Enterprise Edition Porque Java EE tem sido tão utilizado? O que é Java Enterprise Edition? A plataforma Java Enterprise Edition APIs Co Contêiners Deployment de aplicações
83 83 83 83 94 10 5 10 5 1 16 128 128 1 39 139 110 4 111 5 113 6 113 6 17 14 17 14 18 15 115 8 117 9 117 9 218 1
*Apostilha referente somente ao primeiro módulo do curso Formação Java Web 3Way Networks.
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
21
Java WEB
1. JDB DBC C 1.1. Banco de Dados Relacional O banco de dados é onde guardamos os dados que pertencem ao nosso sistema. A maioria dos bancos de dados comerciais hoje em dia são relacionais e derivam de uma estrutura diferente diferente daquela orientada a objetos. Assim como o nome já diz, um banco de dados relacional armazena dados como uma série de informações relacionadas. Grupos relacionados são expressos na forma de tabelas. Cada tabela contém colunas que definem as propriedades de cada grupo de dados armazena arm azenados. dos. As tabelas definidas num banco de dados são geralmente montadas com constraints lógicas que servem para preservar a consistência dos dados. Uma constraint é uma restrição de um tipo de dado: cada coluna é definida para ser de um tipo de dados específico. O sistema automaticamente rejeita a inserção de novos dados que não sejam compatíveis com o tipo de dado definido pela estrutura da tabela. A biblioteca padrão de persistência em banco de dados em Java é a JDBC mas já existem diversos projetos do tipo ORM (Object Relational Mapping) que solucionam muitos problemas que a estrutura da api do JDBC (e ODBC) gerou.
O processo de armazenagem e captura de dados em um banco é chamado de
persistência.
1.2. JDBC – Java Database Database Connectivity Connectivity Java Database Connectivity ou JDBC é um conjunto de classes e interfaces (API) escritas em Java que faz o envio de instru instruçõe çõess SQL SQL para qualquer banco de dados relacional. Por meio meio desta os desenvolvedor desenvolvedores es podem
acessar bases de dados não importando quem seja seu fabricante; os desenvolvedores de um JDBC provêem a implementação para as interfaces definidas nesta API, fornecendo o mesmo grupo de funcionalidades ao desenvolvedor do sistema. As seguintes classes estão na API JDBC: - java.sql.Connection – Representa Representa a conexão com o banco de dados. Encapsula os detalhes de como a comunicação com o servidor é realizada. - java.sql.DriverManager – Gerencia os drivers JDBC utilizados pela aplicação. Em conjunto com o endereço e a autenticação, pode fornecer objetos de conexão. desenvolvedor dor para que se possa possa executar executar comandos SQL. - java.sql.Statement – Fornece meios ao desenvolve - java.sql.ResultSet – Representa Representa o resultado de um comando SQL. Estes objetos normalmente são retornados por métodos. 1.2.1. 1.2.1. java.sql.Dri java.sql.DriverMa verManager nager
Utilizando esta classe, o desenvolvedor pode retornar um objeto de conexão que pode ser usado para executar tarefas relativas ao banco de dados. Dois passos são necessários para tal: - Primeir Primeiro, o, o drive driverr JDBC JDBC deve estar registrado com DriverManager. Isto pode ser feito utilizando o método Class.forName que carrega a classe do driver para a memória. - Segundo, Segundo, utilizando utilizando o método getConnection(), mediante mediante informaçã informação o de uma URL, assim como a senha e o nome do usuário autenticado no banco de dados. A URL deve seguir a sintaxe requisitada pela implementação do banco de dados. Abaixo vemos um exemplo de como se obtém uma conexão com um banco de dados JavaDB (Derby). Novamente, a URL e o driver específicos para para a implementação são utilizados. utilizados. Para outros bancos de dados, verifique a documentação fornecida. Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
31
Java WEB
java.sql.*;
import
public clas public class s JDBCExemplo { static String url = "jdbc:derby://localhost:1527/3way" ; static String usuario = "3way" "3way"; ; "123"; ; static String senha = "123" public pub lic sta stati tic c voi void d main(String[] args) { { try Class. forName("org.apache.derby.jdbc.ClientDriver" ); Connection con = DriverManager. getConnection (url,usuario ,senha); System. out.println("Conectado!" .println("Conectado!"); );
con.close(); }catch(ClassNotFoundException e) { e.printStackTrace(); }catch(SQLException (SQLException e) { e.printStackTrace(); } } }
Teoricamente basta alterar as três Strings que escrevemos para mudar de um banco para outro. Porém não é tudo tão simples assim. Depende de qual padrão SQL o banco suporta. Isso só causa dor de cabeça e existem certos arcabouços que resolvem isso facilmente, como é o caso do Hibernate (www.hibernate.org) (www.hibernate.org) e do JPA JPA.
1.3 Fábrica de Conexõe Con exõess Em determinado momento de nossa aplicação, gostaríamos de ter o controle sobre a construção dos objetos da nossa classe. Muita coisa pode ser feita através do construtor, como saber quantos objetos foram instanciados ou fazer o log sobre essas instanciações. As vezes também queremos controlar um processo muito repetitivo e trabalhoso, como abrir uma conexão com o banco de dados. Tomemos Tomemos como exemplo a classe a seguir que seria responsável por abrir uma conexão com o banco: import
java.sql.*;
public publ ic clas class s static static static
FabricaConexao { String url = "jdbc:derby://localhost:1527/3way" ; String usuario = "3way" "3way"; ; String senha = "123" "123"; ;
public publ ic stat static ic
Connection getConexao() throws SQLException{
try{
Class. forName("org.apache.derby.jdbc.ClientDriver" ); return DriverManager. getConnection (url,usuario ,senha); }catch(ClassNotFoundException e) { throw thr ow new SQLException(e.getMessage()); } } }
Poderíamos colocar um aviso na nossa aplicação, notificando todos os programadores ao adquirir uma conexão: Connection con = FabricaConexao.getConexao(); Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
41
Java WEB
Podemos perceber que o método getConexao() é uma fábrica de conexões, isto é, ele fabrica conexões para nós, não importando de onde elas vieram. Portanto, nada mais natural do que chamar a classe de FabricaConexao e o método de getConexao().
1.4 Criar Banco de Dados e Tabelas Tabelas Devemos criar um banco de dados agenda. Para Para criá-lo você deve editar a url de conexão conexão do banco para: static
String url = "jdbc:derby://localhost:1527/agenda;create=true" ;
A seguinte tabela contatos será usada nos exemplos desse capítulo: contatos ( ID BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY, NOME VARCHAR(255), EMAIL VARCHAR (255), ENDERECO VARCHAR(255), PRIMARY PRIM ARY KEY(id)
CREATE CREA TE TABL TABLE E
);
1.5 Classes Classes Javabeans Javabeans – Entidades Entidades No banco de dados relacional, é comum representar um contato (entidade) em uma tabela de contatos. Agora iremos utilizar: - uma classe classe com método métodoss do tipo get e set para para cada um de de seus parâm parâmetr etros, os, que represe representa nta algum objeto. - uma classe com construtor construtor sem argumentos argumentos que representa representa uma coleção coleção de objetos. A seguir, você vê um exemplo de uma classe javabean que seria equivalente ao nosso modelo de entidade entidade do banco de dados: dados: JavabBeans são public publ ic clas class s
Contato {
private priv ate int
classes que possuem o construtor sem
id; id ;
argumentos e
private
String nome nome; ;
private
String endereco endereco; ;
private
String email email; ;
public pub lic int getId() return id id; ;
métodos de acesso do tipo get e set .
{
} public publ ic void setId( int this.id = id;
id) {
} public String getNome() return nome nome; ;
{
} public publ ic void setNome(String this.nome = nome;
nome) {
} public String getEndereco() return endereco endereco; ;
{
} Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
51
Java WEB
public publ ic void setEndereco(String endereco) this .endereco = endereco;
{
} public String getEmail() return email email; ;
{
} public publ ic void
setEmail(String email) { = email;
this .email
} }
1.6 Inserindo Dados Para inserir dados em uma tabela de um banco de dados entidade relacional basta usar a cláusula INSERT. Precisamos especificar quais os campos que desejamos atualizar e os valores. Primeiro o código SQL: String sql = "insert into contatos (nome,email,endereco) " + "values ('"+ ('"+ nome +"','" + email + "','" + endereco +"')" "')"; ;
O exemplo acima possui dois pontos negativos que são importantíssimos. O primeiro é que o programador que não escreveu o código original não consegue bater o olho e entender o que está escrito. O que o código acima faz? Lendo rapidamente fica difícil. Mais difícil ainda é saber se faltou uma vírgula, um fecha parênteses talvez? talvez? Outro problema é o clássico SQL Injection. O que acontece quando o contato a ser adicionado possui no nome uma aspas simples? O código sql se quebra todo e pára de funcionar ou o usuário final não é capaz de alterar seu código SQL para executar aquilo que ele desejam, tudo isso porque escolhemos aquela linha de código e não fizemos o escape de caracteres especiais. Por esses dois motivos não iremos usar código SQL como mostrado anteriormente... vamos imaginar algo mais genérico e um pouco mais interessante: String sql = "insert into contatos (nome,emai (nome,email,endereco) l,endereco) values (?,?,?)" (?,?,?)"; ;
Perceba que não colocamos os pontos de interrogação de brincadeira, e sim porque realmente não sabemos o que desejamos inserir. Estamos interessados em executar aquele código, mas não sabemos ainda quais são os parâmetros que iremos utilizar nesse código SQL que será executado, executado, chamado de statement. As cláusulas são executadas em um banco de dados através da interface PreparedStatement. Para receber um PreparedStatement relativo à conexão, basta chamar o método prepareStatement , passando passando como argument argumento o o comando SQL com os valores vindos de variáveis preenchidos com uma interrogação. interrogação. PreparedStatement stmt = con.prepareStatement( "insert into contatos(nome,email,endereco) values (?,?,?)" );
Logo em seguida, chamamos o método setString do PreparedStatement para preencher os valores, passando a posição (começando em 1) da interrogação interrogação no SQL e o valor que deve ser colocado. //preenche os valores stmt.setString(1, "3Way Networks"); Networks"); stmt.setString(2, "
[email protected]" ); stmt.setString(3, "Av. 4ª Radial, Radial, 1952 1952 Milão Shopp Shopping ing Center Center" " );
Por fim, uma chamada ao método execute que executa o comando SQL. stmt.execute();
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
61
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
71
Java WEB
Agora imagine todo esse processo sendo escrito toda vez que desejar inserir algo no banco? Ainda não consegue visualizar o quão destrutivo isso pode ser? Veja o exemplo abaixo, que abre uma conexão e insere um contato no banco: public publ ic clas class s JDBCInserir publi pub lic c st stati atic c voi void d try {
{ main(String[] args) throws SQLException
Connection
{
con = ConnectionFactory.getConne ConnectionFa ctory.getConnection(); ction();
// cria um preparedStatement PreparedStatement PreparedStatem ent stmt = (PreparedStatement) (PreparedState ment) con.prepareStatement( "insert into contatos " + " (nome,email,endereco) values (?,?,?)"); (?,?,?)" ); //preenche os valores stmt.setString(1, "3Way Networks"); Networks"); stmt.setString(2, "
[email protected]" ); stmt.setString(3, "Av. 4ª Radial, 1952 Shopping Milão"); Milão" ); //executa stmt.execute(); stmt.close(); System. out.println("Gravado!" .println("Gravado!"); ); con.close(); }catch (SQLException e) { e.printStackTrace(); }finally{ if (con != null ){ con.close(); stmt.close(); } } } }
1.7 Fecha Fechando ndo a Cone Conexão xão O mais pratica praticado do é o uso de alguma alguma API de ORM como o Hibernate ou JPA JPA, porém aqueles que ainda insistem no uso de JDBC devem prestar atenção no momento de fechar a conexão. O exemplo dado acima fecha a conexão caso algum erro ocorra no momento de inserir algum dado no banco de dados. O comum é fechar a conexão em um bloco finally .
1.8 Prepare PreparedStat dStatement ement ou Statemen Statementt Ao invés de usar o PreparedStatement , você pode usar uma interface mais simples chamada Statement, que simplesmente executa uma cláusula SQL no método execute:
Usando Statements , você terá que fazer muitas concatenações,, já com concatenações
PreparedStatements , isso fica mais limpo e fácil.
Statement stmt = con.createStatement(); stmt.execute( "insert into contato contato (nome, email, endereco) values" +"('Nome','Email','Endereco')" ); stmt.close();
É melhor usar a classe PreparedStatement que é mais rápida que Statement e deixa o código muito mais limpo. Geralmente, seus comandos SQL conterão valores vindos de variáveis do programa Java. Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
81
Java WEB
1.9 Design Patterns Orientação à objetos resolve as grandes dores de cabeças que tínhamos na programação procedural, restringindo e centralizando responsabilidades. Mas algumas coisas não podemos simplesmente resolver com orientação à objetos pois não existe palavra chave para uma funcionalidade tão específica. Alguns desses pequenos problemas aparecem com tamanha freqüência que as pessoas desenvolvem uma solução padrão para o mesmo. Com isso, ao nos defrontarmos com um desses problemas clássicos, podemos rapidamente implementar essa solução genérica com uma ou outra modificação. Essa solução padrão tem o nome de Design Pattern (padrão de projeto). O livro mais conhecido de Design Patterns foi escrito em 1995 e tem trechos A melhor maneira de código em C++ e Smalltalk. Mas o que realmente importa são os conceitos e os diagramas que fazem desse livro independente de qualquer linguagem. Além de para aprender o que é tudo, o livro é de leitura agradável: Design Patterns, Erich Gamma et al. um Design Pattern é vendo como surgiu a
1.9.1 DAO – Data Access Object
Já foi possível sentir que colocar código SQL dentro de suas classes de lógica é algo nem um pouco elegante e muito menos viável quando você precisa manter o seu código. A idéia a seguir é remover o código de acesso ao banco de dados de suas classes de lógica e colocá-lo em uma classe responsável pelo acesso ao mesmo. Assim o código de acesso ao banco de dados fica em um lugar só, conseqüentemente, conseqüentemente, mais fácil dar manutenção manutenção ao mesmo. Que tal seria se pudéssemos chamar um método adiciona que adiciona um Contato ao banco? Em outras palavras quero que o código a seguir funcione:
necessidade do mesmo.
// adiciona o os dados no banco Misterio bd = new Misterio(); bd.adiciona(“meu nome”, “meu email”, “meu endereço ”);
Mas... Java é orientado a Strings? Vamos tentar novamente: em outras palavras palavras quero que o código a seguir funcione: // adiciona um contato no banco Misterio bd = new Misterio(); // método muito mais elegante bd.adiciona(contato);
Tentaremos chegar ao código anterior: seria muito m uito melhor e mais elegante poder chamar um único método responsável responsável pela inclusão, certo? public publ ic clas class s
TestaInsere {
public pub lic sta static tic voi void d try
main(String[] args) {
{ //pronto para gravar Contato contato = new Contato(); contato.setNome( "3Way" "3Way"); ); contato.setEmail( "
[email protected]" ); contato.setEndereco( "Av. 4ª Radial, Goiânia-GO"); Goiânia-GO" ); //grave nessa conexão!!! ContatoDAO dao = new ContatoDAO(); Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
91
Java WEB
//método elegante dao.adiciona(contato); System. out.println("Gravado!" .println("Gravado!"); ); } catch (SQLException e) { e.printStackTrace(); } } }
O código anterior já mostra o poder que iremos alcançar, através de uma única classe seremos capazes de acessar o banco de dados e, mais ainda, somente através dessa classe será possível acessar os dados. Esta idéia inocente a primeira vista, é capaz de isolar todo o acesso a banco em classes bem simples, cuja instância é um objeto responsável por acessar os dados. Da responsabilidade deste objeto surgiu o nome de Data Access Object ou simplesmente simplesmente DAO, um dos mais famosos padrões de desenvolvimento. desenvolvimento. O que falta para o código acima funcionar é uma classe chamada ContatoDAO com um método chamado adiciona. Vamos criar uma classe que se conecta ao banco de dados ao ser construída uma instância da mesma: import import import
java.sql.Connection; java.sql.SQLException; conexao.FabricaConexao;
public publ ic clas class s ContatoDAO { conexao; ; private Connection conexao public ContatoDAO() throws SQLException { this.conexao = FabricaConexao.getConexao();
} }
Agora que todo ContatoDAO possui uma conexão com o banco podemos focar no método adiciona, que recebe um Contato como argumento e é responsável responsável por adicionar o mesmo através de código sql. public publ ic void
adiciona(Contato contato) throws SQLException SQLException {
PreparedStatement stmt = (PreparedStatement) this .conexao.prepareStatement( "insert into contatos(nome,email,endereco) values (?, ?, ?)" ); stmt.setString(1,contato.getNome()); stmt.setString(2,contato.getEmail()); stmt.setString(3,contato.getEndereco()); stmt.execute(); stmt.close(); } 1.9.2 Pesquisando
Para pesquisar também utilizamos a interface PreparedStatemen PreparedStatementt, de forma que o método executeQuery retorna todos os contatos no exemplo a seguir. O objeto retornado é do tipo ResultSet que permite navegar por seus registros através do método next() . Esse método irá retornar false quando chegar ao fim da pesquisa, portanto portanto ele é normalmente utilizado para fazer um loop nos registros como no exemplo a seguir: // pega a conexão e o Statement Connection con = ConnectionFactory.getConnection(); PreparedStatement stmt = con.prepareStatement( "select * from contatos" contatos"); ); // executa um select ResultSet rs = stmt.executeQuery(); Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 10
Java WEB
// itera no ResultSet (rs.next()) { } rs.close(); stmt.close(); con.close();
while
Para retornar o valor de uma coluna no banco de dados basta chamar um dos métodos get do ResultSet, dentre os quais, o mais comum: getString(). // pega a conexão e o Statement Connection con = ConnectionFactory.getConnection(); PreparedStatement stmt = con.prepareStatement( "select * from contatos" contatos"); ); // executa um select ResultSet rs = stmt.executeQuery(); // itera no ResultSet while (rs.next()) { System.out.println(rs.getString( "nome" "nome") ) + " :: " + rs.getString("email" rs.getString("email")); )); } stmt.close(); con.close();
1.9.3 Recurso avaçando: O Cursor
Assim como o cursor do banco de dados, só é possível mover para o próximo registro. Para permitir um processo de leitura para trás é necessário especificar na abertura do ResultSet que tal cursor deve ser utilizado. Mas, novamente, podemos aplicar as idéias de DAO e criar um método getLista() no nosso ContatoDAO: PreparedStatement stmt = this.conexao.prepareStatement( "select * from contatos"); contatos" ); ResultSet rs = stmt.executeQuery(); List
contatos = new ArrayList(); (rs.next()) { Contato contato = new Contato(); contato.setNome(rs.getS tring(“nome”));
while
contato.setEmail(rs.getString(“email”)); contato.setEndereco(rs.getString(“endereco”));
contatos.add(contato); } rs.close(); stmt.close(); return contatos;
Crie o método getLista na classe ContatoDAO. public
List List getLista() throws SQLException {
PreparedStatement stmt = (PreparedStatement) this.conexao.prepareStatement ("select * from contatos" contatos"); ); ResultSet rs = stmt.executeQuery(); List contatos = new ArrayList(); (rs.next()) { Contato contato = new Contato(); contato.setNome(rs.getString( "nome" "nome")); ));
while
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 11
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 12
Java WEB
contato.setEmail(rs.getString( "email" "email")); )); contato.setEndereco(rs.getString( "endereco" "endereco")); )); contatos.add(contato); } rs.close(); stmt.close(); return contatos; }
Vamos usar o método getLista() agora para listar todos os contatos do nosso banco de dados. Crie uma classe chamada TestaListaDAO com um método main: Crie um ContatoDAO: ContatoDAO dao = new ContatoDAO();
Liste os contatos com o DAO: List contatos = dao.getLista();
Itere nessa lista e imprima as informações dos contatos: for
(Contato contato : contatos) { System.out.println( "Nome: " + contato.getNome()); System.out.println( "Email: " + contato.getEmail()); System.out.println( "Endereço: " + contato.getEndereco() + "\n" "\n"); );
} 1.9.4 Alteração
Agora que você já sabe usar o PreparedStatement para executar qualquer tipo de código SQL e ResultSet para receber os dados retornados da sua pesquisa fica simples, porém maçante, escrever o código de diferentes métodos de uma classe típica de Dao. Veja primeiro o método altera, que recebe um contato cujos valores devem ser alterados: altera(Contato contato) throws SQLException { PreparedStatement stmt = (PreparedStatement) connection.prepareStatement( "update contatos set nome=?, email=?, endereco=? where id=?" ); stmt.setString(1, contato.getNome()); stmt.setString(2, contato.getEmail()); stmt.setString(3, contato.getEndereco()); stmt.setLong(4, contato.getId()); stmt.execute(); stmt.close();
public publ ic void
} 1.9.5 Exclusão
Não existe nada de novo nas linhas acima. Uma execução de query! Simples, não? Agora o código para remoção: começa com uma query baseada em um contato, mas usa somente o id dele para executar a query do tipo delete: public publ ic void
remove(Contato contato) throws SQLException { PreparedStatement stmt = (PreparedStatement) Connection.prepareStatement( "delete from contatos where id=?"); id=?" ); stmt.setLong(1, contato.getId()); stmt.execute(); stmt.close();
} Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 13
Java WEB
2 Introd Introdução ução a Java Java Enterp Enterpris rise e Edition Edition Java EE é multi-plataforma ,
2.1 Porque Java EE EE tem sido tão tão utilizado utilizado? ? Além de ter uma uma vantagem vantagem numérica, pois não elimina elimina parte do mercado que usa um sistema operacional específico, também aumenta a integrab integrabilidad ilidade e da aplicação, aplicação, ou seja, seja, permite permite que às empresa empresass integrem os sistemas que estão rodando em diferentes plataformas, como por exemplo o sistema Web, os sistemas que estão nos MainFrames, os sistemas que são executados executados na máquina do usuário. Esta é uma grande vantagem para grandes corporações que enfrentam a batalha batalha da integração integração de sistemas. Outro fator fundamental no sucesso da plataforma é a participação de grandes empresas na especificação das APIs no Java Community Process, como Oracle, IBM, Apple, que atuam não só na especificação, mas também no desenvolvimento de produtos como Contêiners, IDEs, frameworks, que agregam assim ainda mais confiabilidade a tecnologia. Certamente a existência de diversos Contêiners Open-Source e/ou Gratuitos, também também colabora com o alto índice í ndice de adoção da tecnologia. Além destes fatores, elencamos aqui alguns pontos que podem ser atingidos com Java Java EE, considerados considerados fundamentais fundamentais para a arquitetura dos dos sistemas desenvolvidos atualmente:
ou seja, é uma solução que pode ser utilizada utilizada computadores com sistema operacional Unix , com Linux , com Windows , com Apple e também pode ser utilizada com MainFrames.
Escalabilidade
Trata-se de um dos ades da engenharia de software que pertence à nova economia globalizada e conectada. Uma campanha de marketing pode fazer com que uma pequena empresa cresça de forma abrupta do dia para a noite. É necessário que a sua solução seja capaz de acompanhar o crescimento do negócio. Disponibilidade
Com uma linguagem e plataforma confiáveis, podemos contar com sistemas que rodam simultaneamente em mais de um servidor para prevenção de falhas. Sistemas conhecidos como cluster cluster de servidores servidores permitem que aplicativos fiquem distribuídos e à prova de falha no data-center hospedeiro. hospedeiro. Performance
Quando o assunto é computação distribuída, Java tem uma performance muito boa em comparação a outras tecnologias. Podemos dizer, por exemplo, que Fortran é mais rápido que Java para resolver um algoritmo complexo isoladamente, isoladamente, mas Java, quando distribuído entre servidores, não possui concorrente. Baixo custo de manutenção
Código bem escrito, objetos bem definidos e documentados, herança, polimorfismo, interfaces da orientação a objeto e outros aspectos técnicos tornam um software simples de ser mantido no decorrer do tempo, quando bem planejado e escrito em Java. Sabemos que os aplicativos tendem a ter um ciclo de vida cada vez mais duradouro na empresa, por isto o custo c usto de manutenção do software se torna cada vez mais importante.
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 14
Java WEB
2.2 O que é Java Java Enterp Enterprise rise Edit Edition ion? ? Java Enterprise Edition é uma plataforma de desenvolvimento desenvolvimento de componentes para aplicações em multi-
camada, que disponibiliza uma série de serviços de infra-estrutura de alto nível, evitando o desenvolvimento de código complexo e aproximando aproximando os desenvolvedore desenvolvedoress do negócio em si. Algumas das especificações de componentes mais importantes da plataforma Java Enterprise Edition são: - JavaServer Pages (JSP): utilizadas para criar páginas Web; - Servlets: geralmente utilizado para construir a camada de controle da aplicação, viabilizando a integração entre as páginas JSP e a camada de negócios; - Enterprise JavaBeans: utilizados para criar componentes distribuídos, representando dados ou regras de negócio. Nenhum destes destes componentes foi foi idealizado para ser executado executado diretamente pela máquina virtual, todos eles devem ser executados e controlados por um Contêiner específico como podemos observar na figura abaixo:
Figura 2.1 – Java Java EE servidores servidores e contêiners contêiners
Web Contêiner: hospeda Servle Servlets, ts, JSPs JSPs (Java (Java Server Server Page Pages) s) e arquivos estáticos ( HTMLs, JavaScript, XML);
utiliza qualquer classe Java como, por exemplo, APIs de envio de e-mail ou acesso a banco de dados. EJB Contêiner: hospeda Enterprise JavaBeans (EJB) que, por sua vez, também pode utilizar uma série de APIs Java, tais como envio de e-mail e acesso a banco de dados. Database: Representamos aqui um banco de dados, mas poderíamos, a partir de uma arquitetura Java EE, acessar arquivos, sistemas legados, ERPs, fila de mensagens e qualquer outra fonte de dados.
2.3 A platafor plataforma ma Java Java Enterpr Enterprise ise Edition Edition Item
Descrição
Blueprints Design Guidelines for Java EE
Padrões de codificação e modelagem desenvolvidos por técnicos altamente capacitados, reunindo em documentos e exemplos de código, as melhores práticas de desenvolvimento de aplicação Java EE. Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 15
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 16
Java WEB
Compat Compatibi ibility lity Test Test Suite Suite
Proces Processo so formal formal de teste de compati compatibil bilida idade de de Application Server Java EE , garantindo a padronização entre os servidores de diferentes fabricantes.
Reference Reference Implementa Implementation tion A plataforma plataforma inclui um servidor servidor chamado de R.I. (Reference Implementation) implementado com 100% das funcionalidades especificadas. Pode ser utilizado para validar aplicações Java EE, sendo 100% gratuito e com código fonte disponível. APIs
Enterprise JavaBeans, Java Servlets API, Java Server Pages, XML e Messaging.
2.3.1 APIs O conjunto de APIs Java EE é definido, em sua maioria, por interfaces que podem ser empregadas pelos desenvolvedores das aplicações corporativas. Tais APIs possuem vínculos com o núcleo (kernel) do servidor que executa tarefas voltadas para o gerenciamento de recursos e infra-estrutura. Podemos dizer que, ao desenvolvermos aplicações Java EE através do uso de APIs disponibilizadas no Java Enterprise Edition (Reference Implementation), elas podem ser executadas nos servidores de aplicações que tenham implementado as especificações técnicas dos servidores JAVA EE. Contamos com as seguintes APIs na plataforma Java EE: API
Descrição
JDBC Extension
Extensão da API JDBC.
Enterprise JavaBeans (EJB)
Componentes gerenciados pelo EJB Contêiner, que oferece serviços de transação, multi-threading, persistência automática, entre outros para os componentes.
Java Servlets
Componentes frequentemente utilizados para integração entre as páginas Web e a camada de negócio.
JavaServer Pages (JSP)
API utilizada principalmente para construção de páginas dinâmicas.
Java Me Message Se Service (J (JMS)
API pa para tr tratamento de de mensagens assíncronas.
Java Transaction API (JTA)
API para controle manual de transações.
JavaMail
Utilizada para envio e recebimento de e-mails.
Java Java API for for XML XML Process Processing ing ( JAXP) Processame Processamento nto de XML. Java Naming Interface ( JNDI)
and
Directory API que oferece acesso a Catálogo de Objetos.
Java Connector Architecture
API que padroniza os conectores para integração de aplicações.
Java API for XML Web Services (JAX- APIs para construção e utilização de Web Services. WS)
2.3. 2.3.2 2 Cont Contê êine iners Contêiners são servidores de objetos, também chamados de servidores de aplicação que oferecem
serviços e infra-estrutura infra-estrutura para a execução de componentes. componentes. O conceito de Contêiner é independente da plataforma Java EE, utilizado em outras linguagens e plataformas. plataformas. Existem outros tipos de Contêiner utilizados em Java, considera-se a seguinte divisão de perfil de Contêiners Java e Java EE: Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 17
Java WEB
T ipo
Descrição / Exemplo
Responsável Responsável pelo ciclo de vida da aplicação, gerenciamento gerenciamento de eventos, bibliotecas, entre outros. Client-side
Exemplos: Applet Contêiner - para painéis gráficos desenvolvidos com AWT/Swing AWT/Swing controlados por browser; Application client Contêiner - aplicações standalone (AWT/Swing), podendo, opcionalmente, ser distribuídas por Java Web Start.
Um Contêiner server-side, gerencia, além do ciclo de vida de componentes, recursos e meios de acesso. Configuramos no Contêiner os recursos que desejamos disponibilizar para que nossas aplicações os acessem através de APIs de serviços, como no caso de um pooling de Conexões a Banco de Dados. Server-side Exemplos: Web Contêiner - para objetos dirigidos por HTTP (Servlets e JSP) ; EJB Contêiner - para objetos de negócio server-side.
Além da definição das interfaces na API, Java Enterprise Edition também especifica como o Contêiner deve ser, quais recursos ele deve obrigatoriamente implementar, quais serviços ele deve oferecer. Permitindo assim que diversas empresas implementem seus próprios Contêiners. Contêiners. Veja a seguir uma pequena amostra de empresas e organizações que desenvolvem Contêiners Java EE: - Sun (GlassFish) (GlassFish) - IBM (WebSp (WebSphere here)) - Oracle Oracle (OAS) (OAS) - BEA Systems Systems (WebLogic) - Red Hat (JBoss) (JBoss) - Apache Apache (Geronimo (Geronimo)) - Adobe Adobe (Jrun) (Jrun) - Borland Borland (AppSever (AppSever))
Aplicações desenvolvidas desenvolvidas de acordo com a especificação podem ser instaladas instaladas em qualquer Contêiner .
A lista completa de empresas licenciadas em Java EE e o teste de compatibilidade associado pode ser encontrada em http://java.sun.com/j2ee/licensees.html . Como já vimos, a plataforma Java EE está fortemente baseada baseada em Contêiners, como o foco do nosso curso é o desenvolvimento de aplicações Java para Web, nosso alvo são os Web Contêiners. Alguns dos serviços oferecidos oferecidos pelos Web Contêiners são: - Gerenciamento Gerenciamento dos recursos utilizados pelos componentes, componentes, como pool de conexões; - Gerenciamento Gerenciamento do ciclo de vida dos componentes componentes (Servlets, JSPs e Custom Tags); - Gerenciamento Gerenciamento de sessões sessões de usuários; usuários; - Controle Controle de acesso. acesso. As duas principais APIs suportadas por um Contêiner Web são: Java Java Servlets Servlets e Java Java Server Server Pages Pages. A implementação de referência de Contêiner Web é o Tomcat. Observe que há alguns servidores que se denominam compatíveis com o JAV JAVA A EE, mas que não passaram pelo teste teste de compatibilidade. Em caso de dúvidas, dúvidas, pode-se encontrar uma lista dos Contêiners JAVA EE na seguinte URL: http://java.sun.com/j2ee/comp http://java.sun.com/j2ee/compatibility.htm atibility.html l Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 18
Java WEB
2.3.3 2.3.3 Deploy Deploymen mentt de aplica aplicaçõe çõess Normalmente a estrutura de diretórios utilizada em desenvolvimento não é a mesma estrutura utilizada dentro do servidor. Além disto, nos diretórios de desenvolvimento temos os arquivos fonte, enquanto no servidor temos apenas os arquivos compilados. O trabalho de mover os arquivos estáticos da estrutura de desenvolvimento para o Contêiner Web, assim como, o da compilação das classes Java, é conhecido como deployment e existem duas opções para a realização desta operação. Podemos gerar um empacotamento WAR para o nosso aplicativo, ou então, copiar diretamente os arquivos para dentro do Contêiner, Contêiner, seguindo uma estrutura de diretórios conforme será apresentada mais adiante (deployment aberto ou expandido). Este trabalho pode ser feito: - Manualmente: copiando os arquivos e organizando organizando dentro do Contêiner na estrutura necessária; - Através Através de ferramentas ferramentas oferecidas oferecidas pelo próprio Contêiner; - Por ambiente de de desenvolvimento desenvolvimento (IDE); - Por ferramentas ferramentas específicas como Ant e Maven.
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 19
Todos os direitos reservados a 3Way Networks
Seja um Profission Profissional al Aprendendo Aprendendo com Profission Profissionais ais www.3way.com.br
1 20
Siga-nos também no Twitter! twitter.com/3waynet