JavaRush /Blog Java /Random-ES /Creando una aplicación web simple usando servlets y jsp (...
fatfaggy
Nivel 26
Киев

Creando una aplicación web simple usando servlets y jsp (parte 2)

Publicado en el grupo Random-ES
Continúo describiendo el proceso de creación de una aplicación web utilizando servlets, jsp, Maven y Tomcat. Principio del artículo , si es necesario.
Creamos entidades.
Creemos una clase de Usuario en el paquete de entidades, en la que crearemos dos variables de cadena privadas, nombre y contraseña. Creemos constructores (predeterminado y uno que acepte ambos valores), getters/setters, anulemos el método toString() por si acaso, así como los métodos equals() y 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; } } Ahora podemos comenzar a crear una lista de usuarios, donde agregaremos nuestros usuarios y desde donde los tomaremos para mostrarlos. Pero hay un problema. Nosotros no creamos nuestros objetos servlet; Tomcat los crea por nosotros. Los métodos que anulamos en ellos también ya están definidos para nosotros y no podemos agregar un parámetro. ¿Cómo podemos entonces crear una lista común que sea visible en ambos servlets? Si simplemente creamos nuestro propio objeto de lista en cada servlet, resultará que agregaremos usuarios a una lista, pero mostrar una lista de usuarios que usan el servlet ListServlet será completamente diferente. Resulta que necesitamos un objeto que sea común a ambos servlets. En términos generales, necesitamos un objeto que sea común a todas las clases de nuestro programa; el único objeto para todo el programa. Espero que hayas oído algo sobre los patrones de diseño. Y quizás para algunos esta sea la primera necesidad real de utilizar la plantilla Singleton en su programa. Puede ser creativo y crear un singleton interesante, con doble verificación y sincronización (sí, tenemos una aplicación multiproceso, ya que Tomcat ejecuta servlets en diferentes subprocesos), pero usaré la opción con inicialización temprana, ya que en este caso bastante adecuado.
Creando un modelo.
Luego crearemos una clase (e implementaremos la plantilla singleton en ella) en el paquete del modelo, y también la llamaremos Modelo de manera bastante colorida. Creemos un objeto de lista de usuarios privado en él y creemos dos métodos: uno para que pueda agregar un usuario y el segundo, que simplemente devuelva una lista de cadenas (nombres de usuario). Dado que nuestro objeto de usuario consta de un nombre y una contraseña, no nos gustaría "revelar" las contraseñas de los usuarios, por lo que solo devolveremos una lista de sus nombres. 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()); } }
Un poco sobre mvc.
Dado que ha oído hablar de singleton, significa que probablemente haya oído hablar de otro patrón de diseño: MVC (modelo-vista-controlador, o en ruso modelo-vista-controlador, o simplemente como en inglés modelo-vista-controlador). Su esencia es separar la lógica empresarial de la presentación. Es decir, separe el código que determina qué hacer del código que determina cómo mostrar . La Vista (vista o simplemente vistas) es responsable de la forma en que se presentan algunos datos. En nuestro caso, las vistas son nuestras páginas JSP. Por eso los puse en una carpeta llamada vistas. El modelo son los datos reales con los que trabaja el programa. En nuestro caso, se trata de usuarios (lista de usuarios). Bueno, los controladores son el vínculo que los une. Toman datos del modelo y los transfieren a vistas, o reciben algunos datos de Tomcat, los procesan y los transfieren al modelo. La lógica empresarial (es decir, qué hacer ) debe describirse en ellos, y no en el modelo o en la vista. Así, cada uno hace lo suyo:
  • el modelo almacena datos
  • Las vistas dibujan una hermosa representación de los datos.
  • Los responsables procesan los datos.
Esto les permite a todos ser bastante simples y fáciles de mantener. Y no un volcado monstruoso de todo el código en una clase. MVC no sólo es adecuado para la programación web, sino que sigue siendo muy común (si no siempre) en esta área. En nuestro caso, los servlets actuarán como controladores. Sí, esta es una descripción muy superficial e incluso aproximada de este patrón, pero este artículo no trata sobre patrones de diseño, sino sobre cómo crear una aplicación web sencilla :) ¿Quién quiere saber más? ¡ Google lo sabe todo ! :) Volvamos a nuestras opiniones.
Cree un formulario para agregar un usuario.
Agreguemos un formulario al archivo add.jsp, que consta de dos entradas de texto (una normal y la otra de tipo contraseña) y un botón para enviar datos al servidor. Aquí el formulario tiene un atributo de método con el valor de publicación. Esto significa que los datos de este formulario se enviarán al servidor en forma de solicitud POST. El atributo de acción no está especificado, lo que significa que esta solicitud irá a la misma dirección donde fuimos a esta página (/add). Por lo tanto, nuestro servlet, que está vinculado a esta dirección, al recibir una solicitud GET, devuelve este jsp con el formulario para agregar usuarios, y si recibe una solicitud POST, entonces este formulario ha enviado sus datos allí (que recuperaremos de el objeto de solicitud en el método doPost(), procesarlo y transferirlo al modelo para guardarlo). Vale la pena señalar que las entradas aquí tienen un parámetro de nombre (para un campo con un nombre tiene el nombre del valor, y para un campo con una contraseña tiene el valor pass). Este es un punto bastante importante. Dado que para obtener estos datos (nombre y contraseña que se ingresarán) de la solicitud (ya dentro del servlet), usaremos exactamente estos nombres y contraseñas. Pero hablaremos de eso más adelante. El botón para enviar datos en sí vuelve a tener la forma de un botón y no de una entrada, como suele ser habitual. No sé qué tan universal es esta opción, pero a mí me funciona en Chrome :)
Procesando una solicitud POST con un servlet.
Volvamos al servlet AddServlet. Ya sabemos que para que nuestro servlet pueda "captar" solicitudes GET, anulamos el método doGet() de la clase HttpServlet. Para enseñarle a nuestro servlet a capturar también solicitudes POST, también anulamos el método doPost(). Recibe objetos de solicitud y respuesta similares de Tomcat, con los que trabajaremos. Primero, extraigamos de la solicitud el nombre y pasemos los parámetros que envió el formulario (si los nombró de manera diferente en el formulario, entonces esos serán los nombres que escriba). Luego crearemos nuestro objeto de usuario utilizando los datos recibidos. Luego obtendremos el objeto del modelo y agregaremos el usuario creado al 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); }
Transferir datos a la vista.
Ahora pasemos al servlet ListServlet. Ya hemos implementado el método doGet(), que simplemente transfiere el control a la vista list.jsp. Si aún no lo tienes, hazlo por analogía con el mismo método del servlet AddServlet. Ahora sería bueno obtener una lista de nombres de usuario del modelo y pasarlos a la vista, que los recibirá allí y los mostrará correctamente. Para hacer esto, usaremos nuevamente el objeto de solicitud que recibimos de Tomcat. Podemos agregar un atributo a este objeto, dándole algún nombre y, de hecho, el objeto en sí que nos gustaría transferir a la vista. Debido al hecho de que al transferir el proceso de ejecución de un servlet a una vista, pasamos allí los mismos objetos de solicitud y respuesta que recibió el servlet, luego, al agregar nuestra lista de nombres al objeto de solicitud, podemos desde esta solicitud El objeto en la vista crea nuestra lista de nombres de usuarios y obtiene. Hemos terminado con la clase ListServlet, así que aquí está el código para toda la clase. 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); } }
Ejecutando código java en archivos jsp.
Ahora pasemos al archivo list.jsp. Este archivo solo se ejecutará cuando ListServlet pase el proceso de ejecución aquí. Además, en ese servlet ya preparamos una lista de nombres de usuarios del modelo y la pasamos aquí en el objeto de solicitud. Dada una lista de nombres, podemos ejecutar un bucle for a través de ella e imprimir cada nombre. Como ya dije, los archivos jsp pueden ejecutar código java (en principio, esto es lo que los diferencia de las páginas html estáticas). Para ejecutar algún código, basta con colocar una construcción en el lugar que necesitamos, <% // java código %> dentro de dicha construcción tenemos acceso a varias variables: solicitud: nuestro objeto de solicitud, que pasamos desde el servlet, donde simplemente se llamó req respuesta - el objeto de respuesta, en El servlet se llamó resp out - un objeto del tipo JspWriter (heredado del escritor habitual), con la ayuda del cual podemos "escribir" algo directamente en la página html. Out.println("¡Hola mundo!") es muy similar a System.out.println("¡Hola mundo!"), ¡pero no los confundas! out.println() "escribe" en la página html y System.out.println, en la salida del sistema. Si llama al método System.out.println() dentro de la sección con código jsp, verá los resultados en la consola de Tomcat, y no en la página, como podría desear :) Puede buscar otros objetos disponibles dentro de jsp aquí . Usando el objeto de solicitud podemos obtener la lista de nombres que se pasó desde el servlet (adjuntamos el atributo correspondiente a este objeto) y usando el objeto de salida podemos mostrar estos nombres. Hagamos esto por ahora simplemente en forma de lista html: si queremos mostrar la lista solo cuando hay usuarios y, en caso contrario, mostrar una advertencia de que aún no hay usuarios, podemos reescribir un poco esta sección: Ahora que sepa cómo transferir datos de servlets a vistas: podemos mejorar un poco nuestro AddServlet para que se muestre una notificación sobre la adición exitosa de un usuario. Para hacer esto, en el método doPost(), después de agregar un nuevo usuario al modelo, podemos agregar el nombre de este usuario a los atributos del objeto req y devolver el control a la vista add.jsp. Y en él ya cree una sección con código Java, donde puede verificar si dicho atributo está en la solicitud y, de ser así, mostrar un mensaje de que el usuario se ha agregado correctamente. Después de estos cambios, el código completo del servlet AddServlet se verá así: Aquí, al final del método doPost(), configuramos un atributo con el nombre del usuario agregado al modelo y luego llamamos al método doGet( ) método, al que pasamos la solicitud y la respuesta actuales. Y el método doGet() ya transfiere el control a la vista, donde envía un objeto de solicitud con el nombre del usuario agregado adjunto como atributo. Queda por corregir el propio add.jsp para que muestre dicha notificación si dicho atributo está presente. Agregar.jsp final
    <% 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

    El cuerpo de la página consta de un div con un encabezado, después del cual hay un contenedor div para el contenido, en el que se verifica si existe un atributo con el nombre de usuario, luego un div con un formulario para agregar usuarios y al final un pie de página con un botón para volver a la página principal. Puede parecer que hay demasiados divs, pero los usaremos más adelante cuando agreguemos estilos :) Bueno, la versión final es list.jsp. Por lo tanto , tenemos una aplicación web completamente funcional que también puede almacenar y agregar usuarios. como mostrar una lista de sus nombres. Ya sólo queda embellecerlo... :) <%@ 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!

    "); %>
    Añadiendo estilos. Usamos el marco W3.CSS.
    Por el momento, nuestra aplicación está funcionando, pero es una locura :) Necesitamos agregar un fondo, colores para el texto y los botones, estilizar listas, alinear, agregar sangrías, en general muchas cosas. Si escribe estilos manualmente, puede llevar mucho tiempo y nervios. Por lo tanto, sugiero utilizar el marco CSS W3.CSS . Ya tiene clases con estilos listas para usar, solo queda colocar en los lugares correctos las clases CSS que queremos aplicar en esos lugares. Para poder agregarlos a nuestras páginas, primero necesitamos incluir un archivo con estilos. Esto se puede hacer de dos maneras: 1. Vaya a nuestras páginas y en la sección del encabezado inserte un enlace directo al archivo con estilos, esta opción es adecuada si tiene una conexión constante a Internet. Luego, cuando abra sus páginas en un servidor local, los estilos se extraerán de Internet. 2. Si desea tener todos los estilos localmente y no depender de una conexión a Internet, simplemente puede descargar el archivo con estilos y colocarlo en algún lugar dentro de la carpeta web (por ejemplo web/styles/w3.css), y luego revise todas nuestras páginas (index.html, add.jsp, list.jsp) e ingrese un enlace a este archivo con estilos dentro de la sección principal. Después de eso, simplemente revise las etiquetas y etiquételas con los estilos que desee. . No me detendré en esto en detalle, pero inmediatamente daré mis versiones listas para usar de mis tres archivos con clases de estilo ordenadas. index.html add.jsp list.jsp Eso es todo :) Si todavía tienes alguna pregunta o comentario, o por el contrario, algo no funciona, deja un comentario. Bueno, adjuntaré un par de capturas de pantalla de lo que salió de todo. Y finalmente. Si quieres practicar con este proyecto, puedes probar: 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 de inicio de la aplicación Agregar ventana de usuario una lista de usuarios
    • cree un servlet y jsp para eliminar un usuario y un par más para cambiar/editar un usuario existente. Obtendrá una aplicación web CrUD real :) en servlets))
    • reemplazar lista (Lista ) para trabajar con la base de datos para que los usuarios agregados no desaparezcan después de reiniciar el servidor :)
    ¡Buena suerte!
    Comentarios
    TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
    GO TO FULL VERSION