domingo, 13 de março de 2016

Web - Retorno a Simplicidade com JSP e MongoDB

A anos programo com Java, principalmente com JSP, e o único detalhe que percebo é que as pessoas deixaram de ser simples. Por exemplo, muitos reclamam que no aviso de emprego é exigida muita coisa do profissional solicitado. Porém o único culpado disso é o próprio profissional (ou talvez o Arquiteto). Me pergunto se realmente essa complexidade toda é realmente necessária.
Atualmente para criar qualquer sistema Web é necessário conhecimento (vou citar apenas Java para não me estender muito) de: Linguagem Java, HTML 5, CSS 3, Bootstrap, JQuery, JSON, JSF ou Struts 2 ou Spring ou os três, Symphony, Hibernate, JDBC, vários Design Patterns Java e J2EE, JBoss ou outro Application Server e Banco de Dados. Porém o que o profissional não entende é que do lado do cliente muito pouca coisa mudou. Então do ponto de vista dele "porque tenho que pagar mais para receber a mesma coisa"? ou seja, o salário de um programador com essa gama de conhecimento não mudou para o tempo que só precisava de JSP, HTML, TomCat e Banco.

Toda essa mudança foi criada buscando facilitar a "modificação" do sistema, porém o que ninguém percebeu é que estávamos complicando muito o desenvolvimento, acabamos por tornar os sistemas muito mais difíceis de gerar e dar manutenção com suas 6 ou 7 camadas. Quando acontece um erro o profissional não tem a menor noção nem por onde começar.

Resolvi criar um pequeno sistema para incluir dados em um banco NoSQL e percebi que o mínimo necessário de requisitos seria:
  • Conhecimento de Java Básico.
  • Conhecimento de HTML 5 (CSS 3 e Bootstrap apenas se desejar melhorar o visual).
  • Conhecimento de JSP e JSTL.
  • Uso de 2 padrões de projeto J2EE (TO e DAO).
  • Uso do TomCat (qual a finalidade de um Application Server se não desejo usar EJB?).
  • Conhecimento das funções do Conector do Banco de Dados.

Preparação do Ambiente

Referência: Entenda como funciona a conexão MongoDB e Java através dessa apostila.
Básico: Java instalado, MongoDB instalado, Eclipse instalado e Servidor Web TomCat instalado.
Básico 2: Configure o TomCat no Eclipse

Abra o Eclipse e crie um projeto Dynamic Web Project e na pasta WEB-INF\lib insira as seguintes bibliotecas:
Vamos começar pela configuração do site, na pasta WEB-INF crie um arquivo chamado "web.xml" e insira a seguinte codificação:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Escola</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
Este arquivo contém as informações básicas para o Servidor Web na hora de tratar as páginas, somente foram colocadas duas informações: 1. Nome do Sistema e 2. Quem será a página inicial.

Camada Visual

Todas as páginas JSP devem ser criadas abaixo da pasta WebContent. Como não desejo popular de códigos a index.jsp (página inicial) colocaremos apenas a seguinte codificação para chamar a página de cadastro dos alunos:
<h1>Escola de Alunos</h1>
<ul>
 <li><a href="IEaluno.jsp">Cadastro de Alunos</a>
 <li><a href="IEprofessor.jsp">Cadastro de Professores</a>
</ul> 
Apenas uma chamada HTML, note que já deixei a chamada ao cadastro de Professores, este será seu exercício como forma de implementá-lo para verificar se realmente aprendeu algo.  O resultado de sua execução será este:

A página de cadastro de alunos (IEaluno.jsp) está dividida em duas partes conforme o código a seguir:
<!DOCTYPE html>
<html>

<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<head>
<%
  response.setHeader("Cache-Control", "no-cache");
  response.setHeader("Cache-Control", "no-store");
  response.setHeader("Pragma", "no-cache");
  response.setDateHeader("Expires", 0);
%>
</head>

<body>
  <form action="ICaluno.jsp">
    Nome: <input name="nome"><br /> 
    Nota: <input name="nota"><br /><br />
    <input type="submit" />
  </form>
  <h2>Alunos</h2>
  <jsp:useBean id="alunoDAO" scope="page" class="dao.AlunoDAO" />
  <table>
    <tr>
      <th>Nome</th>
      <th>Nota</th>
    </tr>
    <c:forEach var="al" items="${alunoDAO.obter}">
      <tr>
        <td>${al.nome}</td>
        <td>${al.nota}</td>
      </tr>
    </c:forEach>
  </table>
</body>
</html>
A primeira parte é o formulário que chamará a próxima página para enviar os dados e proceder a inclusão e a segunda parte é uma listagem de todos os alunos que estão no banco.  O resultado de sua execução será este:

A próxima página (ICaluno.jsp) envia as informações ao TO e a DAO e realiza o procedimento de inclusão.
<!DOCTYPE html>
<html>

<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<body>
  <jsp:useBean id="aluno" scope="page" class="to.Aluno" />
  <jsp:setProperty name="aluno" property="nome" value="${param.nome}" />
  <jsp:setProperty name="aluno" property="nota" value="${param.nota}" />

  <jsp:useBean id="alunoDAO" scope="page" class="dao.AlunoDAO" />
  <jsp:setProperty name="alunoDAO" property="aluno" value="${aluno}" />
  <SCRIPT>
    alert("" + <jsp:getProperty name="alunoDAO" property="inserir" />
        + " aluno inserido com sucesso.");
    history.go(-1)
  </SCRIPT>
</body>
Com os dados do formulário preenchemos um objeto TO e esse objeto é enviado para a DAO proceder a inclusão. O resultado de sua execução será este:

Camada de Negócios

Todos os arquivos .java devem ser criados abaixo da pasta src (que se encontra dentro de Java Resources), crie nesta 2 pacotes dao e to. O padrão TO (Transfer Object) é muito simples, é uma classe que representa um registro do arquivo, já o DAO (Data Access Object) é o que faz toda a implementação e conversação com o Banco de Dados. Normalmente os arquitetos complicam a vida adicionando mais 4 padrões: BO (Bussiness Object), VO (Value Object), DTO (Data Transfer Object) e POJO (Plain Old Java Object). Não pretendo discutir o uso ou o valor de cada um deles deixarei isso para os arquitetos, pois como disse aqui busco a simplicidade.

No pacote TO crie a classe Aluno.java com a seguinte codificação:
package to;

public class Aluno {

  private String nome;
  private int nota;
  
  public Aluno() {
  }
  public Aluno(String nome, int nota) {
    setNome(nome);
    setNota(nota);
  }
  
  public String getNome() {
    return nome;
  }
  public void setNome(String nome) {
    this.nome = nome;
  }
  public int getNota() {
    return nota;
  }
  public void setNota(int nota) {
    this.nota = nota;
  }
}
Observe que não existe nada demais aqui, uma classe Java normal com métodos GET/SET. Mantive 2 construtores apenas para respeitar o padrão Bean. Agora vamos para a camada DAO, Crie uma ENUM (TipoColecao) com a seguinte codificação:
package dao;

public enum TipoColecao {
  ALUNO, PROFESSOR;
}
Entenderemos a existência dessa classe na próxima classe criada que será herdada por qualquer outra classe deste pacote e por esse motivo ela é abstrata:
package dao;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoCollection;
import org.bson.Document;

public abstract class DAO {

  protected MongoCollection col;
  private MongoDatabase db;
  private MongoClient mongo;
  
  protected boolean conectar() {
    try {
      mongo = new MongoClient("localhost", 27017);
      db = mongo.getDatabase("escola");
    } catch (Exception e) {
      return false;
    }
    return true;
  }
  
  protected void setColecao(TipoColecao tpCol) {
    switch (tpCol) {
    case ALUNO:
      col = db.getCollection("aluno");
      break;
    case PROFESSOR:
      col = db.getCollection("professor");
      break;
    }
  }
  
  protected boolean desconectar() {
    try {
      mongo.close();
    } catch (Exception e) {
      return false;
    }
    return true;
  }
}
Esta classe contempla os três métodos que toda DAO deve realizar: conexão com o banco, ajuste da tabela (que no MongoDB é chamada de Coleção) correta através do tipo definido na Enum criada e desconexão com o banco. A classe de implementação para Aluno (AlunoDAO.java) possui a seguinte codificação:
package dao;

import java.util.ArrayList;
import java.util.List;
import com.mongodb.client.MongoCursor;
import org.bson.Document;

import to.Aluno;

public class AlunoDAO extends DAO {

  private Aluno aluno;

  public Aluno getAluno() {
    return aluno;
  }

  public void setAluno(Aluno aluno) {
    this.aluno = aluno;
  }

  public int getInserir() {
    if (conectar()) {
      setColecao(TipoColecao.ALUNO);
      Document doc = new Document("nome", aluno.getNome())
        .append("nota", aluno.getNota());
      col.insertOne(doc);
      desconectar();
      return 1;      
    }
    return 0;
  }

  public List getObter() {
    List lista = new ArrayList();
    if (conectar()) {
      setColecao(TipoColecao.ALUNO);
      MongoCursor cursor = col.find().iterator();
      Document doc;
      while (cursor.hasNext()) {
        doc = cursor.next();
        Aluno al = new Aluno(doc.getString("nome"), doc.getInteger("nota").intValue());
        lista.add(al);
      }
      cursor.close();
      desconectar();  
    }
    return lista;
  }
}
Basicamente, é criado um objeto da TO referente a Aluno com a implementação do seus métodos padrão GET/SET e mais dois métodos (observe que ambos são do padrão GET - isso é obrigatório para a chamada padrão da JSP) o primeiro realiza a inclusão do registro no banco e o segundo a busca de uma lista de objetos TO contendo os alunos já cadastrados.

Tudo pronto, agora basta iniciar o TomCat e obter o resultado. Como teste realize a parte dedicada a Professor e note como é fácil trabalhar com JSP e o MongoDB em uma Aplicação Web multi camadas sem ter que complicar muito.

Obrigado e até a próxima
Fernando Anselmo

0 comentários:

Postar um comentário