CodeGym /Blog Java /Random-ES /Creación de una aplicación web sencilla mediante servlets...
John Squirrels
Nivel 41
San Francisco

Creación de una aplicación web sencilla mediante servlets y JSP (parte 1)

Publicado en el grupo Random-ES
Conocimientos necesarios para comprender el artículo: ya ha descubierto más o menos Java Core y le gustaría ver las tecnologías JavaEE y la programación web . Sería más sensato que estuvieras estudiando actualmente la búsqueda de colecciones de Java , que trata temas cercanos al artículo.
Creando una aplicación web simple usando servlets y JSPs (parte 1) - 1
Este material es la continuación lógica de mi artículo Creación del proyecto web más simple en IntelliJ Idea Enterprise . En ese artículo, demostré cómo crear una plantilla de proyecto web funcional. Esta vez te mostraré cómo crear una aplicación web simple pero totalmente atractiva usando la API de Java Servlet y la API de JavaServer Pages . Nuestra aplicación tendrá una página de inicio con dos enlaces:
  • un enlace a una página para agregar usuarios;
  • un enlace a la lista de usuarios.
Como antes, usaré IntelliJ Idea Enterprise Edition , Apache Maven (solo conectaremos algunas dependencias) y Apache Tomcat . Al final, "embelleceremos" nuestra aplicación utilizando el marco W3.CSS . Asumiremos que ya tiene un proyecto vacío que ahora agregaremos. Si no, repase el primer artículo y haga uno. Solo tomará unos minutos :)

Un poco sobre la estructura de nuestra futura aplicación

Nuestra página de inicio (/) será una página HTML estática ordinaria con un encabezado y dos enlaces/botones:
  • agregar un nuevo usuario (navega a / agregar );
  • ver la lista de usuarios (navega a / lista ).
Tomcat captará las solicitudes de estas direcciones y las enviará a uno de los dos servlets que vamos a crear (especificaremos la asignación en web.xml ). Luego, los servlets procesarán las solicitudes, prepararán los datos (o guardarán los datos, si estamos agregando un usuario) y transferirán el control a los archivos JSP apropiados , que luego "presentarán" el resultado. Almacenaremos los datos en una simple lista de vainilla (Lista).

Crear una página de inicio estática

Si index.jsp en su carpeta web, elimínelo. En su lugar, cree un archivo HTML simple llamado index.html en esta carpeta:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My super project!</title>
</head>
<body>
    <!-- header -->
    <div>
        <h1>Super app!<//h1>
    </div>

    <div>       <!-- content -->
        <div>    <!-- button holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
No hay nada complicado aquí. En la etiqueta del título , indicamos el título de nuestra página. En el cuerpo de la página, tenemos dos divisiones principales: encabezado y contenido . El div de contenido incluye un soporte para nuestros botones. Y ahí tenemos dos botones que te llevan a la dirección correspondiente con un click. Puede ejecutar el proyecto y ver cómo se ve ahora. Si hace clic en los botones, obtiene páginas de error 404, porque las páginas correspondientes aún no existen. Pero podemos decir que los botones funcionan. Tenga en cuenta que este no es el enfoque más universal: si JavaScript está desactivado en el navegador, estos botones no funcionarán. Pero supondremos que nadie deshabilita JavaScript. :) Obviamente, puedes arreglártelas con enlaces simples, pero prefiero los botones. Puedes hacerlo como prefieras. Y no se preocupe por el hecho de que mis ejemplos tendrán muchos divs . Los llenaremos con estilos más tarde, y todo se verá más hermoso. :)

Cree archivos JSP para representar el resultado

En el mismo directorio web , cree una carpeta donde agregaremos nuestros archivos JSP . Lo llamé ' vistas ', pero una vez más puedes improvisar. En esta carpeta, crearemos dos archivos JSP:
  • add.jsp — una página para agregar usuarios;
  • list.jsp — página para mostrar la lista de usuarios.
Asígneles encabezados de página apropiados. Algo así como " Agregar nuevo usuario " y " Lista de usuarios ", y lo dejaremos así.

Crear dos servlets

Los servlets recibirán y procesarán las solicitudes que les envíe Tomcat . En la carpeta src/main/java , crea el paquete de la aplicación , donde colocaremos nuestro código fuente. Otros paquetes también irán allí. Entonces, para evitar que estos paquetes se creen uno dentro de otro, crearemos alguna clase en el paquete de la aplicación (la eliminaremos más tarde). Ahora cree tres paquetes diferentes en el paquete de la aplicación :
  • entidades : nuestras entidades (la clase que describe los objetos de usuario) van aquí;
  • modelo : aquí es donde va nuestro modelo (hablaremos de esto un poco más adelante);
  • servlets , y aquí es donde van nuestros servlets.
Una vez que haya hecho esto, puede eliminar tranquilamente esa clase del paquete de la aplicación (si la creó, por supuesto). En el paquete de servlets , cree dos clases:
  • AddServlet — procesa las solicitudes enviadas a / add ;
  • ListServlet : procesa las solicitudes enviadas a / list .

Conexión de dependencias en Maven

Tomcat 9. * implementa las especificaciones para Servlet 4.0 y JavaServer Pages 2.3 . Eso es lo que se indica en la segunda línea del primer párrafo de la documentación oficial de Tomcat 9. Esto significa que si usted, como yo, usa esta versión de Tomcat , entonces el código que escribirá y ejecutará usará estas versiones. Pero nos gustaría tener estas especificaciones en nuestro proyecto, para que nuestro código, que las usa, al menos compile con éxito. Y para hacer esto, necesitamos cargarlos en nuestro proyecto. Aquí es donde Maven viene al rescate.

La regla general es esta: si necesita conectar algo a su proyecto usando Maven:

  • vaya al sitio web del repositorio de Maven;
  • busque la versión requerida de la biblioteca requerida;
  • obtenga el código de dependencia que debe pegarse en su pom.xml;
  • ¡pegar! :)
Vamos a empezar. Primero, prepare el archivo POM . En algún lugar después de la entrada /version , pero antes de /project , inserte lo siguiente:

<dependencies>

</dependencies>
Hacemos esto para indicar que enumeraremos las dependencias requeridas dentro de estas etiquetas. Ahora ve a mvnrepository.com . Hay un campo de búsqueda en la parte superior. Para comenzar, busque ' servlet '. El primer resultado, que ha sido utilizado más de siete mil veces, nos conviene. Recuerde, necesitamos la versión 4.0 (para Tomcat 9). Otras versiones pueden ser apropiadas para implementaciones anteriores. Esta es una versión bastante reciente, por lo que no hay muchos usos. Pero lo necesitamos. Se abre una página donde puede obtener el código de esta dependencia para una variedad de administradores de paquetes, o simplemente puede descargarlo. Pero como queremos conectarlo usando Maven, seleccionaremos el código en la pestaña Maven. Copiamos y pegamos en la sección de dependencias de nuestro archivo POM. Si recibe una notificación que le pregunta si desea habilitar la importación automática en la esquina inferior derecha de IDEA , continúe y acéptelo. Si se negó accidentalmente, vaya a " Configuración " y active la importación automática manualmente: Configuración (Ctrl + Alt + S) -> Compilación, Ejecución, Implementación -> Maven -> Importación .y los archivos de configuración de IDEA para este proyecto sincronizados. Siguiendo el mismo principio, buscaremos y conectaremos JavaServer Pages 2.3 (busque "JSP"). Y como ya comenzamos Maven, digamos que nuestros archivos fuente siguen la sintaxis de Java 8 y que necesitamos compilarlos en código de bytes para esa versión. Después de todos estos pasos, nuestro pom.xml se verá así:

<?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>cc.codegym.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compile.source>1.8</maven.compile.source>
        <maven.compile.target>1.8</maven.compile.target>
    </properties>

    <dependencies>
        <!-- Servlet API 4.0 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JavaServer Pages API 2.3 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

Convierte nuestros servlets en servlets reales

Por el momento, el par de servlets que creamos son en realidad clases ordinarias. No tienen ninguna funcionalidad. Pero ahora hemos conectado la API de Servlet a nuestro proyecto y, en consecuencia, podemos usar sus clases. Para hacer que nuestros servlets sean "reales", todo lo que tenemos que hacer es hacerlos heredar la clase HttpServlet .

Mapeo o marcado

Ahora sería bueno decirle de alguna manera a Tomcat que las solicitudes de la dirección / add son procesadas por nuestro AddServlet , y las solicitudes de la dirección / list son manejadas por el ListServlet . Este proceso se llama mapeo (marcado). Esto se hace en web.xml usando el mismo principio:
  • para comenzar, describa el servlet (proporcione algún nombre y especifique la ruta a la clase en sí);
  • luego vincule este servlet a una dirección específica (especifique el nombre del servlet, que acabamos de darle, y especifique la dirección cuyas solicitudes deben enviarse a este servlet).
Describa el servlet:

<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Ahora vincúlelo a la dirección:

<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
Como puede ver, servlet-name es el mismo en ambos casos. Como resultado, Tomcat sabe que si se recibe una solicitud de /add, debe enviarse a app.servlets.AddServlet. Hacemos lo mismo con el segundo servlet. Al final, nuestro web.xml tiene aproximadamente el siguiente contenido:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
         version="3.1">

    <!-- add servlet -->
    <servlet>
        <servlet-name>add</servlet-name>
        <servlet-class>app.servlets.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>add</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

    <!-- list servlet -->
    <servlet>
        <servlet-name>list</servlet-name>
        <servlet-class>app.servlets.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>list</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>
Por cierto, no creamos marcas para la página de inicio (/). El hecho es que no lo necesitamos en este caso. Nuestra página de inicio es un archivo HTML simple que solo muestra dos botones. No tiene contenido dinámico, por lo que no necesitamos crear un servlet separado para las solicitudes de / que no hará más que enviar la ejecución a algún JSP (que también tendría que crearse) para dibujar dos botones para nosotros. No necesitamos esto. Una página estática nos conviene. Cuando Tomcat recibe una solicitud, verificará si hay un solo servlet que pueda procesar la solicitud para esa dirección y luego verá que esta dirección ya contiene el archivo HTML listo., que servirá. Podemos volver a ejecutar nuestra aplicación (reiniciar el servidor o volver a implementarlo, lo que prefiera) y asegurarnos de que la página de inicio esté renderizada, que no se rompa nada y que las transiciones ocurran cuando hacemos clic en los botones (aunque nuevamente obtenemos un error). Por cierto, mientras que antes recibíamos un error 404, ahora obtenemos un 405. Significa que el mapeo funcionó y se encontraron los servlets, pero no tenían un método adecuado para manejar la solicitud.

Breve digresión: ¿qué sucede "debajo del capó"?

Probablemente ya hayas pensado en cómo funciona nuestra aplicación en Tomcat. ¿Qué pasa ahí? ¿Y dónde está el método main()? Tan pronto como vaya a localhost: 8080 en su navegador, el navegador envía una solicitud a esta dirección utilizando el protocolo HTTP. Espero que ya sepa que hay muchos tipos diferentes de solicitudes, y las más populares son GET y POST. Cada solicitud debe ser respondida. Se espera que una solicitud GET reciba una respuesta de código HTML listo para usar, devuelto al navegador. Luego, el navegador reemplaza el código con todas las letras bonitas, botones y formularios. Una solicitud POST es un poco más interesante, ya que también contiene información. Por ejemplo, suponga que ingresa las credenciales en un formulario de registro o inicio de sesión en un sitio web y hace clic en "Enviar". Esto hace que se envíe al servidor una solicitud POST con su información personal. El servidor recibe esta información, la procesa y devuelve alguna respuesta (por ejemplo, una página HTML con tu perfil). La principal diferencia entre ellos es que las solicitudes GET solo se utilizan para recuperar datos del servidor, mientras que las solicitudes POST contienen cierta información (y los datos en el servidor pueden cambiar). Por ejemplo, cuando carga su imagen en el servidor, se lleva allí en una solicitud POST y el servidor la agrega a la base de datos, es decir, se produce un cambio. Ahora volvamos a Tomcat. Cuando recibe una solicitud de un cliente, mira la dirección. Comprueba si hay un servlet adecuado para procesar las solicitudes de esa dirección (o un recurso disponible que se puede devolver de inmediato). Si no encuentra algo a lo que devolver, luego responde con un error 404 en lugar de una página HTML. Pero si encuentra un servlet adecuado "sentado" en esa dirección, mira el tipo de solicitud (GET, POST o algo más) y le pregunta al servlet si tiene un método que pueda manejar este tipo de consulta. Si el servlet dice que no sabe cómo manejar este tipo, entoncesTomcat devuelve un código 405. Y esto es justo lo que sucedió en nuestro proyecto. Pero si se encuentra un servlet adecuado y tiene un método adecuado, Tomcat crea un objeto de servlet y lo inicia en un nuevo subproceso .(lo que le permite ejecutarse por sí solo), y Tomcat continúa con su propio trabajo, aceptando y enviando solicitudes. Además, Tomcat crea dos objetos más: un HttpServletRequest (que llamaré "solicitud" para abreviar) y un HttpServletResponse (que llamaré "respuesta"). Pone todos los datos recibidos de la solicitud del cliente en el primer objeto, por lo que todos esos datos se pueden extraer de él. Y luego, después de todo esto, pasa estos dos objetos al método apropiado del servlet que se inició en un subproceso separado. Tan pronto como el servlet termina su trabajo y tiene una respuesta lista para ser enviada al cliente, agita una bandera en Tomcat, diciendo "Terminé. Todo está listo". Tomcat recibe la respuesta y la envía al cliente. Esto le permite a Tomcat recibir solicitudes y enviar respuestas, sin distraerse, y todo el trabajo lo realizan servlets que se ejecutan en hilos separados. Eso significa que cuando escribimos el código del servlet determinamos qué trabajo se realizará. Y puede pensar que el método main() está ubicado dentro de Tomcat (sí, está escrito en Java), y cuando "lanzamos" Tomcat, se inicia el método main(). Creación de una aplicación web sencilla utilizando servlets y JSP (parte 1) - 2

Use servlets para capturar métodos GET y enviar respuestas súper simples

Por el momento, nuestros servlets no tienen métodos adecuados (GET), por lo que Tomcat devuelve un error 405. ¡Vamos a crearlos! La clase HttpServlet, que heredamos nuestros servlets, declara varios métodos. Para asignar un código específico a los métodos, simplemente los anulamos. En este caso, necesitamos anular el doGet()método en ambos servlets.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
Como puede ver, este método toma dos argumentos: req (solicitud) y resp (respuesta). Estos son los mismos objetos que Tomcat crea y completa para nosotros cuando llama al método apropiado en el servlet. Para comenzar, crearemos las respuestas más simples. Para hacer esto, tomaremos el objeto resp y obtendremos un objeto PrintWriter de él. Este tipo de objeto se utiliza para redactar una respuesta. Lo usaremos para generar una cadena simple.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("GET method from AddServlet");
}
Haremos algo similar en el ListServlet y luego reiniciaremos nuestro servidor. Como puedes ver, ¡todo funciona! Cuando hace clic en los botones, obtiene páginas con el texto que "escribimos" con PrintWriter. Pero los archivos JSP que preparamos para generar páginas con respuestas no se están utilizando. Eso es simplemente porque nunca son ejecutados. Nuestro servlet crea la respuesta en sí y termina de ejecutarse, indicando a Tomcat que está listo para responder al cliente. Tomcat simplemente toma la respuesta y la envía de regreso al cliente. Pasemos el control de los servlets a los archivos JSP. Cambiaremos el código de nuestros métodos de la siguiente manera:
  • obtenemos un objeto de despachador de solicitudes del objeto de solicitud y le pasamos la dirección de la página JSP a la que queremos transferir el control;
  • usamos este objeto para transferir el control a la página JSP especificada, sin olvidar pasar los objetos de solicitud y respuesta que recibimos de Tomcat.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
En la etiqueta del cuerpo de las páginas JSP, puede agregar algo para que podamos ver claramente qué página se muestra. Una vez que haya hecho eso, reinicie el servidor y verifique. Hacemos clic en los botones de la página principal y se abren las páginas, lo que significa que las solicitudes se envían a los servlets. Luego, el control se pasa a las páginas JSP, que ahora se están procesando. Eso es todo por ahora. En la siguiente parte de este artículo, trabajaremos en la funcionalidad de nuestra aplicación.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION