CodeGym /Blog Java /Random-ES /Tu primera aplicación usando servlets de Java
John Squirrels
Nivel 41
San Francisco

Tu primera aplicación usando servlets de Java

Publicado en el grupo Random-ES
¡Hola a todos! Te familiarizarás con los servlets como concepto básico del desarrollo web y podrás escribir una aplicación sencilla que los utilice. Tu primera aplicación usando servlets de Java - 1 Para evitar acciones innecesarias, no empezaremos desde cero. Continuaremos trabajando en nuestra aplicación de mi artículo anterior sobre Hibernate . Pero como recién estamos empezando a familiarizarnos con los servlets, eliminé todo lo relacionado con la clase Auto de la aplicación y dejé solo la clase Usuario y las acciones que la involucran. El proyecto se estructurará así: Tu primera aplicación usando servlets de Java - 2¡Entonces, servlets! Wikipedia afirma: "Un servlet de Java es un componente de software de Java que amplía las capacidades de un servidor. Aunque los servlets pueden responder a muchos tipos de solicitudes, por lo general implementan contenedores web para alojar aplicaciones web en servidores web y, por lo tanto, califican como servidor- API web de servlet lateral". Esto es exactamente cierto. Aquí, por primera vez, nos encontramos con el concepto de una "arquitectura de aplicación cliente-servidor". Es bastante simple en su esencia. El cliente accede al servidor enviando una solicitud HTTP. El servidor genera los datos necesarios (por ejemplo, los obtiene de una base de datos) y los devuelve al cliente. El ejemplo más simple es cuando hace clic en el botón "Amigos" en una determinada red social, enviando así una solicitud al servidor. El servidor actualiza la lista de tus amigos en la base de datos y te la devuelve a ti (el cliente). La lista de solicitudes HTTP es bastante grande, por lo que si nunca las ha encontrado antes, sería mejor que las leyera en otro lugar, por ejemplo,aquí _ Nuestro objetivo es: Crear una aplicación CRUD usando servlets. La aplicación debe poder crear, leer, actualizar y eliminar usuarios de la base de datos mediante un servlet que procese solicitudes HTTP. Nuestra aplicación del artículo de Hibernate ya podía hacer esto, pero se controlaba directamente desde el código Java, más precisamente, desde el método main(). Esta vez, es el cliente quien enviará las solicitudes, es decir, usted :) Lo primero que debemos hacer es agregar nuevas dependencias a nuestro archivo pom.xml.

 <xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>com.itis4</groupId>
     <artifactId>UsersDaoProject</artifactId>
     <version>1.0-SNAPSHOT</version>
 
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-war-plugin</artifactId>
                 <version>2.6</version>
             </plugin>
         </plugins>
     </build>
 
     <dependencies>
         <!-- PostgreSQL  -->
         <dependency>
             <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>
             <version>9.4.1212.jre7</version>
         </dependency>
 
         <!-- Hibernate 5.2.6 Final -->
         <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-core</artifactId>
             <version>5.2.6.Final</version>
         </dependency>
 
         <dependency>
             <groupId>jstl</groupId>
             <artifactId>jstl</artifactId>
             <version>1.2</version>
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
             <version>3.1.0</version>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-webmvc</artifactId>
             <version>4.3.4.RELEASE</version>
         </dependency>
 
     </dependencies>
 
 </project>
 
Agregamos 3 dependencias:
  1. La propia biblioteca javax.servlet-api
  2. La biblioteca de etiquetas JSTL. Será necesario para crear el lado del cliente, es decir, las páginas JSP
  3. Primavera-WebMVC. Necesitaremos una clase de primavera, de la que hablaremos un poco más adelante.
La gestión de servlets está a cargo del contenedor de servlets. En nuestro caso, utilizaremos Apache Tomcat. Es bastante popular, probablemente ya haya oído hablar de él :) El ciclo de vida del servlet consta de los siguientes pasos:
  1. Si no hay ningún servlet en el contenedor:
    • El contenedor carga la clase de servlet.
    • El contenedor crea una instancia de la clase de servlet.
    • El contenedor llama al método init(). Este método inicializa el servlet y se llama primero, antes de que el servlet pueda atender las solicitudes. Durante todo el ciclo de vida, el método init() se llama solo una vez.
  2. Atender la solicitud del cliente. Cada solicitud se procesa en su propio subproceso independiente. El contenedor llama al método service() para cada solicitud. Este método determina el tipo de solicitud entrante y la envía al método adecuado para su procesamiento. El desarrollador del servlet debe proporcionar implementaciones para estos métodos. Si llega una solicitud para un controlador que no está implementado, se llama al método de la clase principal y generalmente termina devolviendo un error al solicitante.

  3. Si el contenedor necesita eliminar el servlet, llama al método destroy(), que desactiva el servlet. Al igual que el método init(), este método también se llama una vez durante todo el ciclo del servlet.
Nuestro servlet parece bastante simple:

 package servlets;
 
 import models.User;
 import services.UserService;
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletConfig;
 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 UserSimpleServlet extends HttpServlet {
 
     private UserService service = new UserService();
 
     public void init(ServletConfig servletConfig) {
         try {
             super.init(servletConfig);
         } catch (ServletException e) {
             e.printStackTrace();
         }
     }
 
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 
         List<User> users = service.findAllUsers();
         req.setAttribute("users", users);
         RequestDispatcher dispatcher = req.getRequestDispatcher("/showUsers.jsp");
         dispatcher.forward(req, resp);
 
     }
 
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
 
         String name = req.getParameter("name");
         int age = Integer.parseInt(req.getParameter("age"));
         User user = new User(name, age);
         service.saveUser(user);
         resp.sendRedirect("/users");
 
     }
 
     @Override
     protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         int id = Integer.parseInt(req.getParameter("id"));
         User user = service.findUser(id);
         user.setName(req.getParameter("name"));
         user.setAge(Integer.parseInt(req.getParameter("age")));
         service.updateUser(user);
         resp.sendRedirect("/users");
     }
 
     @Override
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         int id = Integer.parseInt(req.getParameter("id"));
         service.deleteUser(service.findUser(id));
         resp.sendRedirect("/users");
     }
 }
 
Como puede ver, contiene el método init(), que se describió anteriormente, e implementa 4 métodos que coinciden con cuatro solicitudes HTTP: doPost(), doGet(), doPut() y doDelete(). Nos permiten crear, leer, actualizar y eliminar usuarios. Los métodos aceptan instancias de las clases javax.servlet.http.HttpServletRequest y javax.servlet.http.HttpServletResponse como entrada, es decir, solicitudes enviadas al servidor y respuestas recibidas por el cliente. Internamente, los métodos llaman a los métodos relevantes de la clase UserService y se genera una respuesta para el cliente y se redirige a la URL /usuarios. Por ejemplo, en el método doGet(), obtenemos una lista de todos los usuarios. A continuación, creamos un objeto RequestDispatcher, que nos permite incluir objetos en una solicitud HTTP y redirigirlo a un recurso específico (por ejemplo, a una página JSP de cliente). En el método doPut() (que actualiza los datos del usuario), procesamos una solicitud HTTP, extraemos los parámetros de identificación, nombre y edad, encontramos al usuario con la identificación especificada, le asignamos el nombre y la edad que aparecen en la solicitud y devolvemos a la página de /usuarios. Pero para que todos estos métodos funcionen correctamente, necesitamos configurar el servlet. Para hacer esto, usamos el archivo web.xml en la carpeta WEB-INF.

 <?xml version="1.0" encoding="UTF-8"?>
 <web-app version="3.1"
          xmlns="http://xmlns.jcp.org/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
 
     <welcome-file-list>
         <welcome-file>index.jsp</welcome-file>
     </welcome-file-list>
 
     <servlet>
         <servlet-name>UserSimpleServlet</servlet-name>
         <servlet-class>servlets.UserSimpleServlet</servlet-class>
     </servlet>
 
     <servlet-mapping>
         <servlet-name>UserSimpleServlet</servlet-name>
         <url-pattern>/</url-pattern>
     </servlet-mapping>
 
     <filter>
         <filter-name>hiddenHttpMethodFilter</filter-name>
         <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
     </filter>
 
     <filter-mapping>
         <filter-name>hiddenHttpMethodFilter</filter-name>
         <servlet-name>UserSimpleServlet</servlet-name>
     </filter-mapping>
 
 </web-app>
 
Todas las etiquetas de este archivo son bastante intuitivas, pero analicémoslas en orden. <welcome-file-list>: se indica la página de inicio de JSP, que se abrirá primero cuando se inicie la aplicación. En nuestro caso, este es index.jsp. <servlet> - Registro de nuestra clase UserSimpleServlet como servlet. <servlet-mapping> - una etiqueta muy importante. Define las URL que serán procesadas por el servlet. En nuestro caso, son todas URLs, por lo que simplemente indicamos "/". Pero si tuviéramos una aplicación que involucre a los usuarios y sus automóviles (automóviles), entonces podríamos crear un segundo servlet (SimpleAutoServlet). Entonces, la asignación del servlet de usuario sería "/usuarios" (es decir, solicitudes sobre usuarios), y la asignación del servlet automático sería "/autos". Y finalmente, <filtro>. Internamente, define una instancia de la organización. clase springframework.web.filter.HiddenHttpMethodFilter. Este artículo no trata sobre Spring, por lo que no lo describiré en detalle. Solo diré que está integrado en nuestra aplicación solo como una característica adicional. La cosa es que vamos a usar páginas JSP para crear el lado del cliente. Nuestros datos se mostrarán en la página como una tabla con una lista de usuarios. Dentro de las páginas JSP, se utilizarán etiquetas HTML <form/>. Pero solo las solicitudes HTTP GET y POST se pueden usar para enviar datos desde un <formulario/>. En otras palabras, para las tres operaciones (actualizar, eliminar y crear un usuario) tendríamos que usar solo solicitudes POST. El uso de solicitudes PUT y DELETE no sería una opción para nosotros. En principio, esto es bastante normal y fácil de implementar, pero la clase HiddenHttpMethodFilter nos permite usarlos. De este modo, el lector verá más claramente la diferencia entre operaciones en la aplicación. Finalmente, pasemos al lado del cliente. Está representado por cinco páginas JSP. índice.jsp.

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
     <title>Hello!</title>
 </head>
 <body>
 If you want to start working with the user database,<br>
 click the button below:
 
 <form action = "users" method="get">
     <input type="submit" value="Start working with database">
 </form>
 </body>
 </html>
 
agregarUsuario.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
     <title>Add new user</title>
 </head>
 <body>
 <form action = "/users" method="post">
     <input required type="text" name="name" placeholder="Name">
     <input required type="text" name="age" placeholder="Age">
     <input type="submit" value="Save">
 </form>
 </body>
 </html>
 
 
eliminarUsuario.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
     <title>Delete user</title>
 </head>
 <body>
 
 Are you sure you want to delete the user ${param.id}?
 
 &lform action="/users/${param.id}" method="post">
     <input type="hidden" name="id" value="${param.id}">
     <input type="hidden" name="_method" value="delete">
     <input type="submit" value="Delete">
 </form>
 
 </body>
 </html>
 
 
mostrarUsuarios.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 <html>
 <head>
     <title>User list</title>
 </head>
 <body>
 <table border="2">
     <tr>
         <td>ID</td>
         <td>Name</td>
         <td>Age</td>
         <td>Actions</td>
     </tr>
     <c:forEach items="${users}" var = "user">
         <tr>
             <td>${user.getId()}</td>
             <td>${user.getName()}</td>
             <td>${user.getAge()}</td>
             <td>
                 <form action = "updateUser.jsp" method="post">
                     <input type="hidden" name="id" value="${user.getId()}">
                     <input type="hidden" name="name" value="${user.getName()}">
                     <input type="hidden" name="age" value="${user.getAge()}">
                     <input type="submit" value="Modify" style="float:left">
                 </form>
                 <form action="deleteUser.jsp" method="post">
                     <input type="hidden" name="id" value="${user.getId()}">
                     <input type="submit" value="Delete" style="float:left">
                 </form></td>
         </tr>
     </c:forEach>
 </table>
 
 <form action = "addUser.jsp">
     <input type="submit" value="Add new user">
 </form>
 </body>
 </html>
actualizarUsuario.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
     <title>Modify user data</title>
 </head>
 <body>
 
 Edit user
 
 <form action="/users/${param.id}" method="post">
     <input type="hidden" name = "id" value="${param.id}">
     <input type="text" name="name" value="${param.name}" placeholder=${param.name}>
     <input type="text" name="age" value="${param.age}" placeholder=${param.age}>
     <input type="hidden" name="_method" value="put">
     <input type="submit" value="Update">
 </form>
 
 </body>
 </html>
 
Una página JSP (JavaServer Page) contiene dos tipos de texto: datos de origen estáticos que se pueden formatear como texto (HTML, SVG, WML o XML) y elementos JSP que se utilizan para crear contenido dinámico. Para ayudarlo a comprender qué es una página JSP, he copiado un pasaje de un artículo muy bueno. "Básicamente, la primera vez que se solicita un JSP, se convierte en un servlet y funciona como un servlet. Esto es muy importante de entender. Una página JSP NO ES como una página HTML : un programador principiante debe entender claramente que este es otro servlet Es solo que no tienes que escribir, tienes que programar cómo se muestra. Simplemente se puede dibujar. Y agregar datos donde sea necesario. Pero debido a que una página JSP recuerda a HTML, un diseñador obviamente lo encontrará más fácil. Y una vez más ENFATIZAR FUERTEMENTE a los principiantes,una página JSP es un SERVLET. Se genera, incluyendo la adición de todos los datos, en el servidor. Aquí es donde se insertan todos los datos. Y en el navegador, el usuario obtiene la página HTML terminada, que no tiene signos de Java". Puede estar seguro de que una página JSP es realmente un servlet, porque cada página tiene un método que debe ejecutarse. Por ejemplo, index .jsp indica que al hacer clic en el botón "Empezar a trabajar con la base de datos" se ejecutará el método get (método = "get"). La página addUser.jsp, que se encarga de crear nuevos usuarios, ejecuta el método post (método = "publicar") cuando hace clic en el botón Guardar. El resto de la página JSP se compone de marcado HTML estático regular, por lo que no nos detendremos en ello. Ese es un tema para otro artículo y hay muchos sobre esto tema en Internet. Entonces, ¡He creado nuestra aplicación! ¡Ahora tenemos que probarlo en acción! Para hacer esto, necesitamos el contenedor de servlet Apache Tomcat mencionado anteriormente. Puedes descargar el contenedordel sitio web oficial (yo uso la versión 8). A continuación, debemos crear una configuración en IDEA para ejecutar nuestra aplicación a través de Tomcat. Para hacer esto, abra la pestaña "Editar configuraciones", Tu primera aplicación usando servlets de Java - 3cree una nueva configuración Tu primera aplicación usando servlets de Java - 4y seleccione "Tomcat Server Local". En la pestaña "Servidor de aplicaciones", especifique la ruta a la carpeta Tomcat. Tu primera aplicación usando servlets de Java - 5A continuación, vaya a la pestaña "Implementación". Tu primera aplicación usando servlets de Java - 6Aquí configuramos el despliegue de nuestra aplicación en el servidor local. Presione "+", seleccione "Artefacto" -> YourProjectName:war (construiremos la aplicación en un archivo war). Tu primera aplicación usando servlets de Java - 7¡Y eso lo resume todo! En la página "Servidor", puede ver que nuestra aplicación se ejecutará en http://localhost:8080/. Guarde la configuración y asígnele un nombre (llamo a mi configuración "Tommy"). Luego, en la pestaña Maven en IDEA (en el lado derecho), usaremos el complemento de guerra para construir nuestro proyecto en un archivo de guerra (Complementos -> guerra -> guerra: guerra). Tu primera aplicación usando servlets de Java - 8Una vez completada la compilación, ejecute la aplicación y espere. ¡Éxito! Se lanzó la página de inicio. Ahora hacemos clic en el botón "Empezar a trabajar con la base de datos". Nuestro index.jsp generará una solicitud GET que será procesada por el servidor. El servidor generará una respuesta y nos la devolverá en forma de una lista de todos los usuarios existentes (suponiendo que haya usuarios en la base de datos, por supuesto). ¡Y ahí están! ¡Que ahí lo tienes! Escribió su primera aplicación utilizando servlets de Java. Tu primera aplicación usando servlets de Java - 9Eso no fue tan malo, ¿verdad? :) Como tarea, podría restaurar la funcionalidad del automóvil del artículo anterior. En otras palabras, cree un servlet y páginas JSP independientes para automóviles y enséñele a la aplicación cómo listar los automóviles de un usuario, agregar automóviles nuevos a un usuario y editarlos y eliminarlos. PS Servlets y JavaServer Pages son tecnologías bastante antiguas. En Internet, a menudo puede encontrar comentarios como "¿Quién necesita esta basura vieja?" La respuesta es bastante simple: principalmente personas que trabajarán en proyectos reales, donde posiblemente encontrarán mucho código que utiliza estas tecnologías. E incluso sin entender cómo funciona, sigue siendo divertido convertir "basura vieja" en algo nuevo :) Para un estudio más completo de JSP y servlets, puede consultar el libro "Head First Servlets and JSP" .. Fue escrito por los mismos autores que el famoso súper libro "Head First Java", que muchos tomarán como garantía de calidad :) ¡Espero que este artículo haya sido de ayuda! ¡Gracias por su atención y buena suerte en el aprendizaje!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION