JavaRush /Blogue Java /Random-PT /Criando uma aplicação web simples usando servlets e jsp (...
fatfaggy
Nível 26
Киев

Criando uma aplicação web simples usando servlets e jsp (parte 2)

Publicado no grupo Random-PT
Continuo descrevendo o processo de criação de uma aplicação web usando servlets, jsp, Maven e Tomcat. Início do artigo , se necessário.
Criamos entidades.
Vamos criar uma classe User no pacote de entidades, na qual criaremos duas variáveis ​​de string privadas nome e senha. Vamos criar construtores (padrão e um que aceite ambos os valores), getters/setters, substituir o método toString() por precaução, bem como os métodos equals() e hashCode(). public class User { private String name; private String password; public User() { } public User(String name, String password) { this.name = name; this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (name != null ? !name.equals(user.name) : user.name != null) return false; return password != null ? password.equals(user.password) : user.password == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (password != null ? password.hashCode() : 0); return result; } } Agora podemos começar a criar uma lista de usuários, onde adicionaremos nossos usuários e de onde os levaremos para exibição. Mas há um problema. Nós não criamos nossos objetos servlet; o Tomcat os cria para nós. Os métodos que substituímos neles também já estão definidos para nós e não podemos adicionar um parâmetro. Como então podemos criar uma lista comum que seria visível em ambos os nossos servlets? Se simplesmente criarmos nosso próprio objeto de lista em cada servlet, adicionaremos usuários a uma lista, mas exibir uma lista de usuários usando o servlet ListServlet será completamente diferente. Acontece que precisamos de um objeto que seja comum aos dois servlets. De modo geral, precisamos de um objeto que seja comum a todas as classes do nosso programa; o único objeto para todo o programa. Espero que você tenha ouvido algo sobre padrões de design. E talvez para alguns esta seja a primeira necessidade real de usar o modelo Singleton em seus programas. Você pode ser criativo e fazer alguns singletons legais, com dupla verificação e sincronização (sim, temos uma aplicação multithread, já que o Tomcat executa servlets em threads diferentes), mas vou usar a opção com inicialização antecipada, pois neste caso é bastante adequado.
Criando um modelo.
Em seguida, criaremos uma classe (e implementaremos o modelo singleton nela) no pacote model, e também a chamaremos de Model. Vamos criar um objeto de lista de usuários privado nele e criar dois métodos: um para que você possa adicionar um usuário e o segundo - deixe-o simplesmente retornar uma lista de strings (nomes de usuários). Como nosso objeto de usuário consiste em um nome e uma senha, não gostaríamos de “revelar” as senhas dos usuários, portanto retornaremos apenas uma lista de seus nomes. public class Model { private static Model instance = new Model(); private List model; public static Model getInstance() { return instance; } private Model() { model = new ArrayList<>(); } public void add(User user) { model.add(user); } public List list() { return model.stream() .map(User::getName) .collect(Collectors.toList()); } }
Um pouco sobre mvc.
Já que você já ouviu falar sobre singleton, significa que provavelmente já ouviu falar de outro padrão de design - MVC (model-view-controller, ou em russo model-view-controller, ou apenas como em inglês model-view-controller). Sua essência é separar a lógica de negócios da apresentação. Ou seja, separe o código que determina o que fazer do código que determina como exibir . A View (view ou apenas visualizações) é responsável pela forma como alguns dados são apresentados. No nosso caso, as visualizações são nossas páginas JSP. É por isso que os coloquei em uma pasta chamada visualizações. O modelo são os dados reais com os quais o programa funciona. No nosso caso, são usuários (lista de usuários). Bem, os controladores são o elo de ligação entre eles. Eles pegam dados do modelo e os transferem para visualizações, ou recebem alguns dados do Tomcat, processam e transferem para o modelo. A lógica de negócios (ou seja, o que fazer ) deve ser descrita neles, e não no modelo ou na visão. Assim, cada um faz o que quer:
  • modelo armazena dados
  • As visualizações desenham uma bela representação dos dados
  • controladores processam dados
Isso permite que todos sejam bastante simples e fáceis de manter. E não um despejo monstruoso de todo o código em uma classe. MVC não é adequado apenas para programação web, mas ainda é muito comum (se não sempre) nesta área. No nosso caso, os servlets atuarão como controladores. Sim, esta é uma descrição muito superficial e até grosseira deste padrão, mas este artigo não é sobre padrões de design, mas sim sobre como fazer uma aplicação web simples :) Quem quer saber mais - o Google sabe tudo ! :) Voltemos às nossas opiniões.
Crie um formulário para adicionar um usuário.
Vamos adicionar um formulário ao arquivo add.jsp, composto por duas entradas de texto (uma normal e outra do tipo senha) e um botão para envio de dados ao servidor. Aqui o formulário possui um atributo de método com o valor post. Isso significa que os dados deste formulário serão enviados ao servidor na forma de uma solicitação POST. O atributo action não está especificado, o que significa que esta solicitação irá para o mesmo endereço onde acessamos esta página (/add). Assim, nosso servlet, que está vinculado a este endereço, ao receber uma solicitação GET, retorna este jsp com o formulário para adição de usuários, e se receber uma solicitação POST, então este formulário enviou seus dados para lá (que recuperaremos de o objeto de solicitação no método doPost(), processe-o e transfira-o para o modelo para salvar). Vale ressaltar que aqui as entradas possuem um parâmetro nome (para um campo com nome possui o valor nome, e para um campo com senha possui o valor pass). Este é um ponto muito importante. Pois para obter esses dados (nome e senha que serão inseridos) da requisição (já dentro do servlet), utilizaremos exatamente estes nome e senha. Mas falaremos mais sobre isso mais tarde. O próprio botão de envio de dados é novamente feito em forma de botão, e não de entrada, como normalmente é habitual. Não sei o quão universal é essa opção, mas funciona para mim no Chrome :)
Processando uma solicitação POST com um servlet.
Voltemos ao servlet AddServlet. Já sabemos que para que nosso servlet seja capaz de “capturar” solicitações GET, sobrescrevemos o método doGet() da classe HttpServlet. Para ensinar nosso servlet a capturar também solicitações POST, também substituímos o método doPost(). Ele recebe objetos de solicitação e resposta semelhantes do Tomcat, com os quais trabalharemos. Primeiro, vamos extrair da solicitação o nome e passar os parâmetros que o formulário enviou (se você os nomeou de forma diferente no formulário, então esses são os nomes que você escreve). Então criaremos nosso objeto de usuário usando os dados recebidos. Então obteremos o objeto do modelo e adicionaremos o usuário criado ao modelo. @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name"); String password = req.getParameter("pass"); User user = new User(name, password); Model model = Model.getInstance(); model.add(user); }
Transferindo dados para a visualização.
Agora vamos passar para o servlet ListServlet. Já implementamos o método doGet(), que simplesmente transfere o controle para a visualização list.jsp. Se você ainda não tem isso, faça-o por analogia com o mesmo método do servlet AddServlet. Agora seria bom obter uma lista de nomes de usuário do modelo e passá-los para a visualização, que os receberá e os exibirá de maneira adequada. Para fazer isso, usaremos novamente o objeto request que recebemos do Tomcat. Podemos adicionar um atributo a este objeto, dando-lhe algum nome e, de fato, o próprio objeto que gostaríamos de transferir para a visualização. Devido ao fato de que ao transferir o processo de execução de um servlet para uma visualização, passamos para lá os mesmos objetos de solicitação e resposta que o próprio servlet recebeu, então, adicionando nossa lista de nomes ao objeto de solicitação, podemos então a partir desta solicitação objeto na visualização, crie nossa lista de nomes de usuário e obtenha. Concluímos a classe ListServlet, então aqui está o código para a classe inteira. package app.servlets; import app.model.Model; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; public class ListServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Model model = Model.getInstance(); List names = model.list(); req.setAttribute("userNames", names); RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp"); requestDispatcher.forward(req, resp); } }
Executando código java em arquivos jsp.
Agora vamos passar para o arquivo list.jsp. Este arquivo só será executado quando o ListServlet passar pelo processo de execução aqui. Além disso, nesse servlet já preparamos uma lista de nomes de usuários do modelo e passamos aqui no objeto request. Dada uma lista de nomes, podemos executar um loop for nela e imprimir cada nome. Como eu já disse, os arquivos jsp podem executar código java (em princípio, é isso que os diferencia das páginas HTML estáticas). Para executar algum código basta colocar uma construção no local que necessitamos, <% // java code %> dentro dessa construção temos acesso a diversas variáveis: request - nosso objeto de solicitação, que passamos do servlet, onde foi simplesmente chamado resposta req - o objeto de resposta, em O servlet foi chamado resp out - um objeto do tipo JspWriter (herdado do Writer usual), com o qual podemos “escrever” algo diretamente na própria página html. Out.println("Hello world!") é muito semelhante a System.out.println("Hello world!"), mas não os confunda! out.println() "grava" na página html e System.out.println - na saída do sistema. Se você chamar o método System.out.println() dentro da seção com código jsp, você verá os resultados no console do Tomcat, e não na página, como você deseja :) Você pode procurar outros objetos disponíveis dentro do jsp aqui . Usando o objeto request podemos obter a lista de nomes que foram passados ​​​​do servlet (anexamos o atributo correspondente a este objeto), e usando o objeto out podemos exibir esses nomes. Vamos fazer isso por enquanto simplesmente na forma de uma lista html: Se quisermos exibir a lista apenas quando houver usuários, e caso contrário exibir um aviso de que ainda não há usuários, podemos reescrever um pouco esta seção: Agora que nós sabemos como transferir dados de servlets para visualizações - podemos melhorar um pouco nosso AddServlet para que uma notificação seja exibida sobre a adição bem-sucedida de um usuário. Para isso, no método doPost(), após adicionar um novo usuário ao modelo, podemos adicionar o nome desse usuário aos atributos do objeto req e passar o controle de volta para a visualização add.jsp. E nele já fazemos uma seção com código Java, onde você pode verificar se tal atributo está na solicitação, e em caso afirmativo, exibir uma mensagem informando que o usuário foi adicionado com sucesso. Após essas alterações, o código completo do servlet AddServlet ficará mais ou menos assim: Aqui, ao final do método doPost(), definimos um atributo com o nome do usuário adicionado ao modelo, e então chamamos o método doGet( ), para o qual passamos a solicitação e a resposta atuais. E o método doGet() já transfere o controle para a view, onde envia um objeto request com o nome do usuário adicionado anexado como atributo. Resta corrigir o próprio add.jsp para que ele exiba tal notificação se tal atributo estiver presente. Adição final.jsp
    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { for (String s : names) { out.println("
  • " + s + "
  • "); } } %>
<% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(" "); for (String s : names) { out.println("
  • " + s + "
  • "); } out.println("
    "); } else out.println("

    There are no users yet!

    "); %>
    package app.servlets; import app.entities.User; import app.model.Model; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class AddServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp"); requestDispatcher.forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name"); String password = req.getParameter("pass"); User user = new User(name, password); Model model = Model.getInstance(); model.add(user); req.setAttribute("userName", name); doGet(req, resp); } } <%@ page contentType="text/html;charset=UTF-8" language="java" %> Add new user

    Super app!

    <% if (request.getAttribute("userName") != null) { out.println("

    User '" + request.getAttribute("userName") + "' added!

    "); } %>

    Add user

    O corpo da página consiste em uma div com um cabeçalho, seguida de uma div container para conteúdo, verificando se existe nele um atributo com o nome do usuário, depois uma div com um formulário para adição de usuários, e no final um rodapé com um botão para retornar à página principal. Pode parecer que há muitos divs, mas vamos usá-los mais tarde quando adicionarmos estilos :) Bem, a versão final é list.jsp. Assim , temos uma aplicação web totalmente funcional que pode armazenar e adicionar usuários, também como exibir uma lista de seus nomes. Só falta embelezar... :) <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> Users

    Super app!

    Users

    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(" "); for (String s : names) { out.println("
  • " + s + "
  • "); } out.println("
    "); } else out.println("

    There are no users yet!

    "); %>
    Adicionando estilos. Usamos a estrutura W3.CSS.
    No momento nosso aplicativo está funcionando, mas absolutamente maluco :) Precisamos adicionar fundo, cores para texto e botões, estilizar listas, fazer alinhamento, adicionar recuos, em geral um monte de coisas. Se você escrever estilos manualmente, pode levar muito tempo e nervosismo. Portanto, sugiro usar o framework CSS W3.CSS . Já possui classes prontas com estilos, só falta colocar nos lugares certos as classes CSS que queremos aplicar nesses locais. Para adicioná-los às nossas páginas, primeiro precisamos incluir um arquivo com estilos. Isso pode ser feito de duas maneiras: 1. percorra nossas páginas e na seção principal insira um link direto para o arquivo com estilos. Esta opção é adequada se você tiver uma conexão constante com a Internet. Então, quando você abrir suas páginas em um servidor local, os estilos serão extraídos da Internet. 2. Se você deseja ter todos os estilos localmente e não depender de uma conexão com a Internet, você pode simplesmente baixar o arquivo com estilos e colocá-lo em algum lugar dentro da pasta web (por exemplo web/styles/w3.css), e então percorra todas as nossas páginas (index.html, add.jsp, list.jsp) e insira um link para este arquivo com estilos dentro da seção head. Depois disso, basta percorrer as tags e marcá-las com os estilos que você gosta . Não vou me alongar sobre isso em detalhes, mas darei imediatamente minhas versões prontas dos meus três arquivos com classes de estilo organizadas. index.html add.jsp list.jsp Isso é tudo :) Se você ainda tiver alguma dúvida ou comentário, ou pelo contrário, algo não deu certo - deixe um comentário. Bem, vou anexar algumas capturas de tela do que resultou de tudo isso. E finalmente. Se quiser praticar com este projeto, você pode tentar: Super app!

    Super app!

    <%@ page contentType="text/html;charset=UTF-8" language="java" %> Add new user

    Super app!

    <% if (request.getAttribute("userName") != null) { out.println("
    \n" + " ×\n" + "
    User '" + request.getAttribute("userName") + "' added!
    \n" + "
    "); } %>

    Add user

    <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> Users list

    Super app!

    Users

    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println("
      "); for (String s : names) { out.println("
    • " + s + "
    • "); } out.println("
    "); } else out.println("
    \n" + " ×\n" + "
    There are no users yet!
    \n" + "
    "); %>
    Página inicial do aplicativo Adicionar janela de usuário uma lista de usuários
    • crie um servlet e jsp para excluir um usuário e mais alguns para alterar/editar um usuário existente. Você obterá um aplicativo da web CrUD real :) em servlets))
    • lista de substituição (lista ) para trabalhar com o banco de dados para que os usuários adicionados não desapareçam após a reinicialização do servidor :)
    Boa sorte!
    Comentários
    TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
    GO TO FULL VERSION