Revisão 2.0

Esta é uma revisão para a segunda prova.

  1. Crie uma aplicação chamada MiniBlog que tenha as seguintes características:

    1. Uma tela que liste todos os posts publicados. Deverá ser listado somente o título e a data dos posts, com um link para ver o post completo.
    2. Outra tela para exibir o post completo.
    3. E uma terceira tela com um formulário que permite publicar posts.

    A aplicação deve ser desenvolvida usando o framework MVC discutido em sala de aula.


    Os posts serão adicionados à tabela Posts:

    CREATE TABLE Posts (
      id      INT PRIMARY KEY IDENTITY,
      titulo  VARCHAR(100) UNIQUE        NOT NULL,
      horario DATETIME DEFAULT GETDATE() NOT NULL,
      texto   TEXT                       NOT NULL
    )

    As classes de acesso a dados Post e PostDao já estão criadas e prontas para uso:

    Post.java
    package model;
    
    import java.util.Date;
    
    public class Post {
        private int id;
        private String titulo;
        private Date horario;
        private String texto;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTitulo() {
            return titulo;
        }
    
        public void setTitulo(String titulo) {
            this.titulo = titulo;
        }
    
        public Date getHorario() {
            return horario;
        }
    
        public void setHorario(Date horario) {
            this.horario = horario;
        }
    
        public String getTexto() {
            return texto;
        }
    
        public void setTexto(String texto) {
            this.texto = texto;
        }
    }
    PostDao.java
    package dao;
    
    import model.Post;
    import org.sql2o.Connection;
    
    import java.util.List;
    
    public class PostDao {
        /**
         * Referência da fábrica de conexões
         */
        private static final Database db = Database.getInstance();
    
        public Post obter(int id) {
            String query =
                "SELECT id, titulo, horario, texto " +
                "FROM Posts " +
                "WHERE id=:id";
    
            try (Connection con = db.open()) {
                return con.createQuery(query)
                    .addParameter("id", id)
                    .executeAndFetchFirst(Post.class);
            }
        }
    
        public List<Post> obterTodos() {
            String query =
                "SELECT id, titulo, horario, texto " +
                "FROM Posts";
    
            try (Connection con = db.open()) {
                return con.createQuery(query)
                    .executeAndFetch(Post.class);
            }
        }
    
        public boolean adicionar(Post post) {
            String query =
                "INSERT INTO Posts (titulo, horario, texto) " +
                "VALUES (:titulo, :horario, :texto)";
    
            try (Connection con = db.open()) {
                con.createQuery(query)
                    .addParameter("titulo", post.getTitulo())
                    .addParameter("horario", post.getHorario())
                    .addParameter("texto", post.getTexto())
                    .executeUpdate();
    
                // Obtém id gerado automaticamente pelo SGBD
                Integer id = con.getKey(Integer.class);
                post.setId(id);
    
                return con.getResult() > 0;
            }
        }
    
        public boolean modificar(Post post) {
            String query =
                "UPDATE Posts " +
                "SET titulo = :titulo, horario = :horario, texto = :texto " +
                "WHERE id = :id";
    
            try (Connection con = db.open()) {
                con.createQuery(query)
                    .addParameter("id", post.getId())
                    .addParameter("titulo", post.getTitulo())
                    .addParameter("horario", post.getHorario())
                    .addParameter("texto", post.getTexto())
                    .executeUpdate();
    
                return con.getResult() > 0;
            }
        }
    
        public boolean excluir(int id) {
            String query =
                "DELETE Posts WHERE id = :id";
    
            try (Connection con = db.open()) {
                con.createQuery(query)
                    .addParameter("id", id)
                    .executeUpdate();
    
                return con.getResult() > 0;
            }
        }
    }
  2. Eu desenvolvi um comando chamado Posts com três subcomandos:

    index
    Lista de posts publicados.
    visualizar
    Exibe o post por completo.
    publicar
    Exibe o formulário de publicação e executa a ação de publicar o post, isto é, armazenar no banco de dados.
    Posts.java (veja a classe do comando)

    Para exibir as páginas do MiniBlog, eu utilizei uma página mestre com um layout básico que recebe dois parâmetros: title e include.

    /master-page.jsp

    Além disso, cada subcomando tem seu próprio fragmento de página:

    /posts/lista.jsp
    /posts/visualizar.jsp
    /posts/adicionar.jsp
  3. Adicione um novo recurso ao MiniBlog, permita que um post só seja publicado na data e hora informada pelo usuário.

    Nesse caso, antes da data informada, o novo post não irá aparecer na lista, nem poderá ser acessado diretamente usando a URL.

  4. Existem basicamente duas formas de solucionar esse problema:

    1. Consultar o banco de dados com WHERE horario <= GETDATE().

      OBS: a função GETDATE() do SQL Server retorna a data/hora atual, assim, a condição irá obter todos os post cujo horário estejam até o horário atual.

    2. Filtrar os resultados usando Java.

      Não recomendável porque aumenta demais o processamento do servidor web.

    Usando a alternativa 1 como solução, eu adicionei o método obterVisiveis() à classe DAO e alterei o comando Posts:index para utilizar esse método em vez de obter todos os posts.

    obterVisiveis() (novo método da classe PostDao)
    Posts:index (comando com alteração)

    E eu modifiquei o controller do comando Posts:visualizar para que o post agendado não seja visualizado diretamente antes do horário de publicação.

    Posts:visualizar (comando com alteração)

    No caso, eu considerei que se o post não pode ser exibido, então o cliente deve receber uma resposta HTTP 404, indicando que a página não existe.