← De Java a la Web: HTTP y Spring Boot

Sesión 1 · Semana 1

Elegir el CRUD y arrancar el servidor

Proyecto compartido. En el taller de Intermodular que abre esta semana has trabajado del repositorio vacío a una url pública. En Servidor continúas la implementación del mismo producto.

Qué vas a construir este trimestre

Este módulo no se evalúa con ejercicios independientes. Durante todo el primer trimestre construyes una sola aplicación de servidor, un CRUD cuyo tema eliges tú, y esa aplicación es la evidencia que se evalúa. Cada sesión le incorpora una capacidad nueva —rutas, JSON, validación, capas, base de datos, pruebas— sobre el mismo código y el mismo repositorio, de modo que lo que decidas hoy te acompaña catorce semanas.

Ese repositorio es también el que utilizas en Proyecto Intermodular, donde se evalúa cómo lo construyes: la descomposición en tareas, las ramas, la revisión por pares y el despliegue. Aquí se evalúa el producto; allí, el método.

La sesión de hoy tiene dos mitades. En la primera decides qué vas a construir; en la segunda dejas el proyecto en marcha, respondiendo por una URL desde tu propio equipo. No necesitas saber todavía diseñar tablas ni interpretar términos como JPA o transacción: la meta del proyecto durante el primer trimestre recoge el nivel de complejidad exigible al final, y cada técnica se explica en la sesión que le corresponde.

Se explica

25 minutos · explicación y demostración

De un programa Java a una aplicación web

Hasta ahora has escrito programas Java que ejecutan instrucciones desde main. Para que otra persona utilice uno de esos programas desde un navegador, necesitamos que pueda recibir peticiones y responderlas. Esa será la parte servidor, o backend, de nuestro proyecto. La parte que muestra pantallas y recoge las acciones del usuario se llama cliente o frontend.

Por ejemplo, en una aplicación de préstamos, el cliente podría mostrar un formulario para solicitar un proyector. El servidor comprobaría su disponibilidad y registraría el préstamo. Hoy empezamos por algo más pequeño: escribir una dirección en el navegador y recibir un texto producido por nuestro programa Java. Todavía no habrá formulario ni datos guardados.

El navegador y el servidor son dos programas distintos. Durante el desarrollo ambos funcionarán en tu ordenador. Más adelante, en Intermodular, publicaremos este mismo backend para acceder a él por Internet.

Qué son Spring, Spring Boot y Maven, y para qué los necesitamos

Spring es un framework de Java: un conjunto de herramientas y convenciones para construir aplicaciones. Nos proporciona, entre otras cosas, una forma de relacionar una petición web con un método Java. Así podemos centrarnos en lo que hace nuestra aplicación.

Spring Boot facilita preparar y arrancar una aplicación que utiliza Spring. Con la opción web incluye un servidor llamado Tomcat, que escucha las peticiones del navegador. «Incluido» significa que se pone en marcha junto con nuestro programa; no tenemos que instalar Tomcat por separado. Spring Boot no sustituye a Java: seguiremos escribiendo clases y métodos Java.

Para utilizar ese código de otras bibliotecas, nuestro proyecto necesita dependencias. Una dependencia es código externo que nuestra aplicación utiliza. Maven es la herramienta que descarga esas bibliotecas, compila nuestro código, ejecuta pruebas y prepara la aplicación para distribuirla. Lee lo que necesita el proyecto en un archivo llamado pom.xml. No escribimos código de la aplicación en Maven.

Elemento Para qué lo utilizaremos hoy
JDK de Java Incluye las herramientas para compilar y ejecutar Java
IDE Editor en el que abrimos el proyecto, escribimos clases y vemos errores
Spring Boot con Spring Web Prepara una aplicación Java capaz de responder a peticiones web
Maven Prepara y ejecuta el proyecto con las dependencias declaradas
Navegador Envía una petición y muestra lo que responde nuestra aplicación
Git y GitHub Git guarda versiones del código; GitHub aloja el repositorio del proyecto

El proyecto incluirá Maven Wrapper: los archivos mvnw y mvnw.cmd. Permiten utilizar la versión de Maven configurada en el proyecto sin instalar Maven por separado. La primera ejecución necesita Internet para descargarla y obtener las dependencias. El JDK sí debe estar instalado.

Qué significa la dirección que vamos a abrir

Usaremos http://localhost:8080/hola. Cada parte tiene una función:

Parte Significado
http:// Usamos HTTP, las reglas con las que cliente y servidor intercambian peticiones y respuestas
localhost El ordenador desde el que estás abriendo el navegador
8080 El puerto en el que escuchará nuestra aplicación; permite distinguirla de otros servicios del ordenador
/hola La ruta que pedimos a esa aplicación

Al escribir esa dirección, el navegador envía una petición de consulta, llamada GET. En Java crearemos un método que devuelva un texto y lo asociaremos a esa ruta. A la combinación de método HTTP y ruta, como GET /hola, la llamaremos endpoint.

La respuesta contiene un estado que indica el resultado, unas cabeceras con información sobre la respuesta y un cuerpo con su contenido. Hoy reconoceremos 200 OK cuando nuestra ruta responde y 404 Not Found cuando pedimos una ruta que no hemos creado. Si el servidor está apagado, no llega ninguno de esos estados: el navegador no consigue conectarse.

En la demostración el profesor arrancará el programa, abrirá /hola y señalará el método que produce su texto. Después cambiará el texto, reiniciará y repetirá la petición. Ese es el recorrido que vas a construir, observar y explicar.

Se trabaja

140 minutos · implementación guiada sobre el proyecto propio

Al terminar tendrás el tema de tu CRUD, una aplicación que responde a tres rutas y su primera versión en GitHub. CRUD significa crear, consultar, modificar y borrar información: lo construiremos progresivamente en este mismo proyecto. Los tiempos de los pasos orientan el taller; si una comprobación falla, utiliza la ayuda de ese paso antes de continuar.

Paso 1 · Elegir un problema que tu aplicación resolverá · 15 min

Este paso fija el tema del proyecto del trimestre. Conviene uno acotado y con reglas propias: algo que conozcas, con cuatro tipos de información y unas pocas condiciones que deban cumplirse siempre. No se trata de una idea original, sino de una que puedas seguir ampliando durante catorce semanas.

  1. Abre una nota y completa: «Mi aplicación la utilizará ___ para ___». Por ejemplo: «Una asociación la utilizará para organizar los préstamos de su material».
  2. Enumera cuatro tipos de información que necesitarás. Los llamaremos entidades. En el ejemplo serían socios, ejemplares de material, préstamos y categorías. Escribe dos datos de cada tipo, como nombre y número de socio. Cuatro socios distintos son cuatro registros, no cuatro entidades.
  3. Elige la entidad principal y describe sus cuatro operaciones CRUD con tus palabras: registrar un préstamo, consultarlo, corregirlo y eliminar un registro equivocado.
  4. Anota tres reglas reales: un ejemplar no se presta dos veces a la vez, una devolución no puede preceder a la salida y un socio bloqueado no puede pedir material.
  5. Describe una acción que afecte a varias cosas: prestar varios ejemplares juntos y cancelar toda la operación si alguno no está disponible. Más adelante aprenderemos cómo garantizarlo.
  6. Acuerda la propuesta con el profesor. Guarda la nota para copiarla después al README, el archivo que presenta el proyecto.

Comprueba: puedes explicar quién lo usará, qué guardará y qué debe impedir, y tu propuesta está acordada con el profesor. La tabla de la meta del proyecto durante el primer trimestre fija el nivel exigible en diciembre; hoy no tienes que saber diseñar sus tablas ni interpretar sus términos.

Paso 2 · Comprobar las herramientas y preparar el editor · 15 min

  1. Abre el IDE preparado para Java en clase. La terminal es su panel para escribir comandos; no es la consola del navegador. Abre ese panel desde el menú de terminal del IDE.
  2. Escribe los siguientes comandos, uno cada vez, y pulsa Intro después de cada uno:
java -version
javac -version
git --version
  1. Comprueba que java y javac muestran Java 21 o una versión compatible posterior. javac es el compilador: si solo funciona java, la preparación del JDK está incompleta. Si un comando «no se reconoce», resuelve la instalación o configuración con el profesor antes de generar el proyecto.
  2. Crea una carpeta de trabajo, por ejemplo Documentos/DAW. Abre GitHub en el navegador e inicia sesión con tu cuenta; todavía no crees otro repositorio si ya tienes uno para este proyecto en Intermodular.

Comprueba: funcionan los tres comandos y sabes dónde guardarás el proyecto. No necesitas ejecutar mvn: utilizaremos el wrapper que se descargará con él.

Si trabajas con Visual Studio Code

Visual Studio Code recién instalado no sabe nada de Java. Abre los archivos y los colorea, pero no compila, no te avisa de errores y no tiene ningún botón para arrancar la aplicación. Todo eso lo aportan dos extensiones, y sin ellas los pasos siguientes no te van a funcionar. Puede que en el equipo del aula ya estén puestas; míralo igualmente, que cuesta un minuto.

  1. Pulsa Ctrl+Shift+X (en macOS, Cmd+Shift+X) o el icono de las piezas de puzle en la barra lateral.
  2. Busca Extension Pack for Java, de Microsoft, y pulsa Install. No es una extensión sino seis: el lenguaje, el depurador, las pruebas, Maven, el explorador de proyectos y las sugerencias de código.
  3. Busca Spring Boot Extension Pack y pulsa Install. Añade el autocompletado de application.properties y el panel desde el que se arrancan las aplicaciones Spring.
  4. Si aparece un aviso pidiendo recargar la ventana, recárgala.

Comprueba: buscando cada uno de los dos en el panel de extensiones, el botón ya no dice Install sino que aparecen como instalados. Todavía no vas a ver ningún proyecto Java por ninguna parte, y es normal: aún no has abierto ninguno. Eso llega en el paso 3.

Si trabajas con IntelliJ

Sáltate este apartado entero: IntelliJ trae de serie el soporte de Java y de Maven. Lo único que tendrás que hacer es confirmar el JDK 21 cuando abras el proyecto en el paso 3.

Paso 3 · Generar la estructura inicial y abrirla · 20 min

Spring Initializr es una web que genera los archivos iniciales de un proyecto Spring Boot. No aloja tu aplicación ni escribe las reglas de tu CRUD.

  1. Abre Spring Initializr. Cada campo determina qué archivos contendrá el ZIP. Rellénalos con estos valores, que son los que utiliza el módulo:
Campo Valor y motivo
Project Maven: es la herramienta de construcción que acabamos de explicar
Language Java: el lenguaje que conoces
Spring Boot 4.1.1: la versión estable, que el generador ofrece marcada por defecto. Ninguna terminada en SNAPSHOT ni en M1
Group com.ejemplo: primera parte del identificador técnico del proyecto
Artifact y Name gestor: nombre técnico del proyecto y de su carpeta
Package name com.ejemplo.gestor: paquete base de nuestras clases
Packaging Jar: formato con el que empaquetaremos la aplicación Java
Java 21
Dependencies Spring Web, que aporta el soporte web y el servidor embebido
Por qué no se elige una versión en previsualización

Junto a la versión estable, el generador ofrece otras marcadas como SNAPSHOT o M1: compilaciones en curso y entregas preliminares, sujetas a cambios y sin garantía de estabilidad. Un proyecto de trabajo toma siempre la estable. Spring Boot mantiene además varias líneas de versión en paralelo y retira cada una del generador cuando concluye su soporte abierto, de modo que la lista cambia a lo largo del curso. Eso no afecta a tu proyecto: en el momento de generarlo, la versión queda escrita en el pom.xml y la construcción deja de depender de lo que el generador proponga después. Es el mismo principio de reproducibilidad que Proyecto Intermodular aplica al pipeline.

Usamos gestor como nombre técnico para que las rutas de archivos de estos primeros pasos coincidan en clase. El nombre público y el tema de tu aplicación quedan en el README. La configuración puede contrastarse con la guía oficial de Spring Boot.

  1. Pulsa Generate. El navegador descarga un ZIP con el nombre del artefacto.
  2. Extrae el ZIP en la carpeta de trabajo. No abras el código dentro del ZIP.
  3. En el IDE elige Abrir carpeta/proyecto y selecciona la carpeta que contiene pom.xml, no la carpeta src. Si pregunta cómo importarlo, elige Maven. Espera a que termine la descarga de dependencias.

En Visual Studio Code es Archivo → Abrir carpeta, y después pasan tres cosas que conviene no despachar a golpe de Intro:

  • Sale un aviso preguntando si confías en los autores de los archivos de esa carpeta. Responde que sí. Si dices que no, el editor entra en modo restringido, Java se queda apagado y nada de lo que viene después va a funcionar.
  • Abajo a la derecha aparece un aviso de que está importando el proyecto Maven, con una barra de progreso. La primera vez tarda un rato largo: está descargando Spring entero. Déjalo terminar antes de tocar nada.
  • En el explorador de archivos, abajo del todo, aparece una sección nueva, JAVA PROJECTS, con gestor dentro. Ésa es la señal de que la importación ha ido bien.

Ahora que el proyecto está abierto, mira qué Java está usando el editor: Ctrl+Shift+P, escribe Java: Configure Java Runtime y ábrelo. Se abre una pestaña con las versiones detectadas y tiene que aparecer 21. Que java -version funcionara en la terminal del paso 2 no significa que el editor use esa misma; son dos cosas que se configuran por separado, y es el fallo que más tiempo hace perder en esta sesión.

Comprueba: ves pom.xml, src, mvnw y mvnw.cmd. Si el IDE muestra otra carpeta gestor dentro, entra en ella: la raíz del proyecto es donde está pom.xml.

Lo que te puedes encontrar en Visual Studio Code, y qué significa

No aparece la sección JAVA PROJECTS, o está vacía. O has abierto una carpeta que no contiene pom.xml, o dijiste que no confiabas en los autores. Cierra la carpeta, vuelve a abrirla y esta vez confía.

Abajo a la derecha pone «Java: Lightweight Mode», o ves un rayo. Es un modo reducido en el que Visual Studio Code lee el código pero no lo compila. Pulsa encima y elige Switch to Standard. Hasta que no esté en modo estándar no vas a tener ni errores marcados ni botón para arrancar.

Los import org.springframework... salen subrayados en rojo. Casi siempre es que todavía está descargando las bibliotecas; abajo verás la barra de progreso. Espera a que acabe. Si termina y siguen en rojo, Ctrl+Shift+P → Java: Clean Java Language Server Workspace y acepta reiniciar.

Dice «The JAVA_HOME environment variable is not defined correctly». El editor no encuentra el JDK. Abre Java: Configure Java Runtime y mira qué versiones detecta; si no sale ninguna, avisa antes de seguir.

Paso 4 · Localizar el código y entender el primer arranque · 15 min

Antes de editar, comprueba que el IDE utiliza el JDK 21 también para este proyecto: que java -version funcione en la terminal no configura automáticamente el compilador del IDE. Abre los archivos de la tabla y señala cuál contiene Java, cuál configura Maven y cuál configura la aplicación. No copies el bloque de GestorApplication si ese archivo ya coincide con la plantilla: se muestra para leerlo y entenderlo.

Archivo o carpeta Qué contiene y qué haces ahora
pom.xml Configuración de Maven. Localiza dependencies y comprueba su contenido con la lista de abajo
src/main/java/com/ejemplo/gestor/GestorApplication.java Clase de arranque. Localiza el método main
src/main/resources/application.properties Ajustes de la aplicación. Hoy puede estar vacío o contener su nombre
src/test/java Código de pruebas. Lo utilizaremos en próximas sesiones
.mvn, mvnw y mvnw.cmd Configuración y comandos del wrapper de Maven

Comprueba el pom.xml antes de seguir. Con los valores de la tabla anterior, el generador declara exactamente dos dependencias, y de ellas depende que la aplicación arranque como servidor:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-webmvc</artifactId>
	</dependency>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-webmvc-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>
Dependencia Qué aporta
spring-boot-starter-webmvc Spring MVC y el servidor Tomcat embebido. Es la que mantiene el proceso vivo a la escucha en un puerto; sin ella la aplicación arranca y termina
spring-boot-starter-webmvc-test El instrumental de pruebas, en ámbito test: JUnit, AssertJ, Mockito y el soporte para probar controladores. No se empaqueta con la aplicación

Si tu archivo declara otras dependencias, o si le falta la primera, seleccionaste una lista distinta en el generador: vuelve a generarlo con Spring Web y solo con ella.

La clase de arranque tendrá esta forma:

package com.ejemplo.gestor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GestorApplication {
    public static void main(String[] args) {
        SpringApplication.run(GestorApplication.class, args);
    }
}

main sigue siendo el punto de entrada que conoces. Su llamada a SpringApplication.run pone en marcha Spring Boot. Una anotación es una marca que empieza por @ y aporta información sobre el código: aquí @SpringBootApplication identifica la configuración de arranque. Conserva este archivo; el controlador irá en otro.

Comprueba: puedes señalar dónde se inicia el programa y dónde se declaran sus dependencias. Todavía no hay ninguna ruta /hola: la crearemos en el paso 6.

Paso 5 · Arrancar y reconocer una aplicación que escucha · 15 min

  1. Abre la terminal del IDE en la carpeta de pom.xml. Comprueba su ubicación con pwd y lista los archivos con ls; ambos comandos funcionan también en PowerShell. Si no ves pom.xml, cambia a la carpeta correcta antes de seguir.
  2. En Windows con PowerShell, ejecuta:
.\mvnw.cmd spring-boot:run

En Linux o macOS, el mismo paso se escribe:

./mvnw spring-boot:run

El primer fragmento llama al wrapper de Maven de esta carpeta. spring-boot:run le pide ejecutar la aplicación. Si Linux o macOS dice que no tienes permiso para ejecutar el archivo, aplica chmod +x mvnw y repite el comando.

Con las extensiones instaladas aparecen controles para esta operación: encima del método main aparecen las palabras Run | Debug, y el panel de Spring Boot arranca la aplicación con un play. Hacen lo mismo. En esta sesión se lanza desde la terminal para que la salida sea idéntica para todo el grupo y pueda aprenderse a interpretarla; a partir de la sesión 2 usa el botón si prefieres.

  1. Espera a que aparezcan mensajes que contengan Tomcat started on port 8080 y Started GestorApplication. El texto alrededor puede variar. La terminal queda ocupada porque el servidor sigue funcionando: no es un bloqueo.
  2. Abre http://localhost:8080/ en el navegador. Aparecerá una respuesta de error, normalmente una página Whitelabel Error Page con estado 404. Has llegado al servidor, pero todavía no has programado qué debe devolver la ruta /.
Si ocurre esto Qué revisar
La aplicación escribe Started ...Application y termina con BUILD SUCCESS El proyecto no tiene servidor web: se generó sin la dependencia Spring Web. Sin servidor no hay nada que mantenga el proceso vivo, así que termina. Comprueba que spring-boot-starter-webmvc está en el pom.xml y, si falta, vuelve a generar el proyecto con esa dependencia seleccionada
No se encuentra mvnw.cmd La terminal debe estar en la carpeta que contiene ese archivo y pom.xml
Falla la descarga de una dependencia Lee el primer error de descarga y revisa la conexión; no borres bibliotecas al azar
Port 8080 was already in use Puede haber otra ejecución tuya abierta. Detén esa ejecución con el botón Stop del IDE o Ctrl+C en su terminal y repite
El navegador no conecta Comprueba que aparece Started, que el proceso sigue activo y que escribiste http y el puerto correcto

Si otro servicio necesita el puerto 8080, escribe server.port=8081 en application.properties, reinicia y usa 8081 en las direcciones de la práctica. Regístralo en el README.

Comprueba: distingues «el programa ha arrancado» de «existe la ruta que he pedido».

Paso 6 · Crear una ruta que devuelva un texto · 20 min

Un controlador es una clase que agrupa métodos para atender peticiones. Vamos a crear uno dentro del paquete base que Spring Boot revisa al arrancar.

  1. En src/main/java/com/ejemplo/gestor, crea la carpeta o paquete controller desde el IDE. Dentro crea la clase HolaController. Su archivo debe quedar en src/main/java/com/ejemplo/gestor/controller/HolaController.java.
  2. Escribe la clase completa:
package com.ejemplo.gestor.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HolaController {
    @GetMapping("/hola")
    public String hola() {
        return "Hola, mundo. Te responde mi servidor.";
    }
}
  1. Relaciona cada parte con su función: package coincide con la ubicación; los import permiten usar las anotaciones; @RestController indica que los resultados de los métodos se envían como respuesta; @GetMapping("/hola") asocia un GET a esa ruta; return proporciona el cuerpo de la respuesta. El nombre del método Java no determina la URL.
  2. Guarda el archivo. En la terminal donde corre el servidor pulsa Ctrl+C, espera a que vuelva el indicador para escribir y ejecuta otra vez el comando de arranque. No hemos añadido recarga automática: editar y refrescar el navegador no basta para ejecutar el código nuevo.
  3. Abre http://localhost:8080/hola. Debes leer exactamente la frase de return.
  4. Cambia la frase por una que presente tu aplicación, guarda, reinicia y recarga. Comprueba que cambia la respuesta.
Qué es exactamente una anotación, y por qué @RestController y no @Controller

Una anotación no ejecuta nada por sí misma: es metadato adherido al código, que permanece en el archivo compilado hasta que algún proceso lo lee. Aquí quien lo lee es Spring durante el arranque.

@SpringBootApplication agrupa tres anotaciones, y una de ellas es @ComponentScan, que activa el escaneo de componentes: Spring recorre el paquete de la clase de arranque y sus subpaquetes, localiza las clases marcadas, las instancia y las registra. De ahí que HolaController atienda peticiones sin que nadie lo invoque desde main, y de ahí que deba colgar de com.ejemplo.gestor, porque fuera de ese paquete no se escanea. Las otras dos habilitan la autoconfiguración y el registro de la configuración propia.

@RestController es una anotación compuesta: está meta-anotada con @Controller y @ResponseBody. La diferencia está en cómo se interpreta el valor que devuelve el método. Con @Controller por separado, ese valor se entiende como el nombre de una plantilla que debe renderizarse como HTML; con @RestController se escribe directamente en el cuerpo de la respuesta, que es lo que requiere una API. Si un método devuelve el texto correcto y el servidor responde con un error de vista, la causa es precisamente esa.

Si obtienes 404, revisa la ruta letra a letra, el reinicio y que HolaController esté bajo com.ejemplo.gestor. Si el IDE marca un error de Java, corrígelo antes de arrancar; no hace falta cambiar el navegador.

Comprueba: puedes recorrer navegador → ruta → método Java → texto de respuesta y señalar tu archivo en ese recorrido.

Paso 7 · Ver tu propia petición en el navegador · 15 min

Las herramientas de desarrollo del navegador permiten observar las peticiones. Vamos a inspeccionar solo la que acabas de crear, cuyo resultado ya conoces.

  1. Con /hola abierto, pulsa F12 o abre el menú del navegador → Herramientas de desarrollo. Elige la pestaña Red o Network.
  2. Deja seleccionado Todo/All y recarga con Ctrl+R. El panel registra lo que se solicita mientras está abierto; por eso hay que recargar después de abrirlo.
  3. Pulsa la fila cuya dirección acaba en /hola. Puede aparecer además favicon.ico, el icono de la pestaña: no es nuestra petición y puedes ignorarlo.
  4. En Cabeceras/Headers, busca URL, método GET y estado 200. Localiza Content-Type entre las cabeceras de respuesta: describe el tipo de contenido. En Respuesta/Response, lee el texto de tu método.
  5. Abre /ruta-que-no-existe, selecciona su fila y observa el 404. Después detén tu servidor y recarga: ahora verás un fallo de conexión, sin respuesta HTTP. Arranca de nuevo y vuelve a /hola para dejarlo funcionando.

Guarda estas observaciones en una tabla provisional; la incorporarás al repositorio en el paso 9:

Situación Método y ruta Resultado observado Explicación
Servidor encendido, ruta creada GET /hola Completa estado y texto Se ejecuta el método del controlador
Servidor encendido, ruta no creada GET /ruta-que-no-existe Completa el estado No existe un método para esa ruta
Servidor apagado GET /hola Describe el mensaje No hay un proceso escuchando para responder

Comprueba: sabes localizar método, dirección, estado, cabeceras y cuerpo sin confundirlos con el código Java.

Paso 8 · Aplicar el patrón a tu proyecto · 10 min

  1. En HolaController, debajo del método hola y antes de la última llave de la clase, añade:
@GetMapping("/estado")
public String estado() {
    return "Servidor en funcionamiento";
}

@GetMapping("/prestamos/resumen")
public String resumen() {
    return "Esta aplicación gestionará los préstamos de material";
}
  1. Cambia prestamos y el texto del segundo método por el recurso principal de tu tema, por ejemplo /reservas/resumen. La respuesta describe el proyecto: todavía no cuenta datos ni consulta una base de datos.
  2. Guarda, reinicia y abre las dos direcciones completas en el navegador. Anota en tu tabla sus estados y textos.

Comprueba: responden tres rutas diferentes y sabes qué método atiende cada una. No copies otra clase completa dentro de HolaController: aquí estás añadiendo dos métodos a la clase existente.

Paso 8-bis · Comprobar lo que la sesión afirma · opcional

Este paso no introduce contenido nuevo: comprueba con evidencia cuatro afirmaciones que la sesión ha hecho sin demostrar. Está previsto para quien termine antes de tiempo; la prioridad es el paso 9, que cierra la sesión con la primera versión publicada. Deshaz cada alteración antes de continuar.

Alteración Resultado esperado Qué demuestra
Renombra el método hola() como saluda(), sin tocar su @GetMapping /hola responde igual que antes El nombre del método Java no determina la URL
Comenta la línea @RestController y reinicia /hola devuelve 404 Sin esa anotación la clase compila igual, pero el escaneo de componentes no la registra como controlador y su ruta no existe
Añade un segundo método, con otro nombre, anotado también con @GetMapping("/hola") La aplicación no llega a arrancar: el registro informa de Ambiguous mapping La correspondencia entre rutas y métodos se resuelve durante el arranque, no al recibir la petición
Añade el método de abajo y compara las cabeceras de ambas rutas Cada una declara un Content-Type distinto El tipo que devuelve el método determina cómo se escribe la respuesta
@GetMapping("/anyo")
public int anyo() {
    return 2026;
}

Para la última comprobación, abre las herramientas de desarrollo del navegador en la pestaña Red y contrasta la cabecera Content-Type de las dos respuestas:

Ruta Tipo devuelto Cabecera Content-Type
/hola String text/plain;charset=UTF-8
/anyo int application/json

Ninguna de las dos ha necesitado configuración alguna: el servidor decide cómo escribir el cuerpo a partir del tipo declarado en el método. Qué componente toma esa decisión, y cómo se gobierna cuando lo que se devuelve es un objeto de tu dominio, es el contenido de la sesión 3.

Comprueba: las cuatro alteraciones están deshechas, /hola devuelve su texto y la aplicación arranca sin errores en el registro.

Paso 9 · Guardar la primera versión en GitHub · 25 min

Un repositorio guarda los archivos y su historial. Un commit registra una versión local; push envía los commits a GitHub. Es el mismo repositorio que utilizaremos en Intermodular para practicar el flujo de trabajo y el despliegue.

Si ya has hecho la primera sesión de Intermodular, estos comandos los has visto con el portfolio. Lo único distinto es que aquí el proyecto ya existe en tu ordenador antes que en GitHub, y por eso se empieza con git init en lugar de con git clone.

  1. En la carpeta de pom.xml, crea el archivo README.md. El generador no lo incluye: entrega un HELP.md con enlaces a la documentación que su propio .gitignore excluye del repositorio. Escribe en el README la propuesta del paso 1, el comando de arranque y tus tres rutas.
  2. Revisa la tabla de comprobaciones de los pasos 7 y 8. Debe indicar la petición, la respuesta observada y cualquier dificultad pendiente. Explica qué parte de la aplicación produce cada respuesta.
  3. Abre .gitignore, el archivo que indica a Git qué no debe subir. Comprueba que excluye target/ (archivos generados al compilar), la configuración local del IDE y .env si lo utilizas más adelante. Conserva los archivos del wrapper, incluidos .mvn/, mvnw y mvnw.cmd.

Conviene entender qué queda dentro del repositorio y qué queda fuera, porque determina cómo se recupera el proyecto en cualquier otro equipo:

Se versiona No se versiona
src, tu código fuente target/, todo lo que produce la compilación
pom.xml, que declara las dependencias Las bibliotecas de las que depende el proyecto
mvnw, mvnw.cmd y .mvn/, el wrapper La configuración local del editor
README.md y .gitignore Credenciales y archivos de entorno

Las dependencias no se guardan: se declaran. Maven las descarga una sola vez y las conserva en el repositorio local de tu equipo, una carpeta .m2 de tu perfil de usuario que queda fuera del proyecto. Por eso el repositorio ocupa unos pocos kilobytes mientras que las bibliotecas que utiliza suman decenas de megabytes, y por eso lo que se comparte es la declaración y no el contenido descargado.

La consecuencia práctica aparece al llevar el proyecto a otro ordenador: basta clonar el repositorio y ejecutar el arranque con el wrapper. Maven lee el pom.xml, resuelve cada dependencia y reconstruye target/ desde cero. No se copian carpetas entre equipos ni se envían bibliotecas por mensajería: se clona y se ejecuta. Es la misma propiedad que hace reproducible el flujo de integración de Proyecto Intermodular, donde la máquina que construye tampoco conserva nada entre ejecuciones.

Si aún no hay repositorio del proyecto, crea uno vacío en GitHub con el botón New repository. No añadas allí README ni .gitignore: ya existen en tu ordenador. Copia su dirección HTTPS. En la terminal del proyecto, ejecuta cada comando por separado:

git init -b main
git status
git add .gitignore README.md pom.xml mvnw mvnw.cmd .mvn src
git diff --cached --stat

init crea el repositorio local, status muestra los cambios, add prepara los archivos para la versión y diff --cached --stat resume lo preparado. Revisa que aparezcan el código y la documentación, sin target/ ni credenciales. Después crea el commit:

git commit -m "Completar sesión 01: primera aplicación servidor"

Si Git pide identidad, configura tu nombre y correo de autor con git config user.name "Tu nombre" y git config user.email "Tu correo de autor", sustituyendo ambos textos por tus datos, y repite el commit.

Conecta el repositorio y sube la versión. Sustituye la dirección siguiente por la que copiaste de GitHub:

git remote add origin https://github.com/TU_USUARIO/TU_REPOSITORIO.git
git push -u origin main

Completa el inicio de sesión que solicite Git. La guía de GitHub para subir código local desarrolla este procedimiento.

Si ya hay repositorio en Intermodular, utiliza su carpeta clonada. Sitúa allí el proyecto sin copiar otra carpeta .git; conserva el README existente y complétalo. No repitas git init ni git remote add: guarda y publica los cambios mediante las ramas y revisiones establecidas en ese módulo.

Comprueba en GitHub: abre el README y el controlador. Contrasta su contenido con tu copia local y localiza en el historial el cambio que acabas de guardar. Debes poder recuperar esa versión del proyecto.

Cierre

15 minutos · resultado comprobable y explicación individual

Al terminar la sesión:

Con tu proyecto abierto, explica para qué utilizas Spring Boot y Maven, señala el método que atiende una de tus rutas y reproduce una respuesta correcta y un 404. Explica qué cambia si detienes el programa. Comprueba también que tu propuesta tiene las entidades y reglas necesarias para seguir ampliándola durante el trimestre.

Para casa · recuperar el proyecto desde el repositorio

La entrega de la sesión no termina en el push: un repositorio solo sirve si otra persona, u otro equipo, puede partir de él. Compruébalo sobre el tuyo.

  1. Clona tu repositorio en una carpeta distinta de la de trabajo, o en otro ordenador si dispones de él: git clone <la dirección de tu repositorio> gestor-copia.
  2. Antes de ejecutar nada, inspecciona la copia. No existe target/ ni ninguna biblioteca: solo el código, el pom.xml y el wrapper.
  3. Abre la carpeta en el editor y espera a que termine de importar el proyecto Maven. Si los import aparecen marcados como error, la importación no ha concluido; el código es correcto y lo que falta es que el editor resuelva las dependencias declaradas en el pom.xml.
  4. Arranca con el wrapper y comprueba que /hola responde el mismo texto que en tu carpeta original.
  5. Ejecuta git status en la copia. Pese a haber compilado, target/ no aparece como cambio pendiente: el .gitignore lo excluye.

Qué traer a la sesión 2: la dirección del repositorio clonado y una nota con lo que tuviste que hacer para ponerlo en marcha, incluido cualquier paso que no estuviera en este guion.

Reto · simular un equipo que nunca ha visto Spring

En tu propio ordenador las bibliotecas ya están descargadas, de modo que la copia arranca de inmediato y la descarga inicial no vuelve a verse. Para reproducirla, indica a Maven un repositorio local vacío:

.\mvnw.cmd -Dmaven.repo.local=..\m2-limpio spring-boot:run en PowerShell, o ./mvnw -Dmaven.repo.local=../m2-limpio spring-boot:run en Linux y macOS.

Maven descargará en esa carpeta todo lo que declara el pom.xml, que es exactamente lo que ocurre la primera vez en una máquina nueva. Compara cuánto tarda esa ejecución con la siguiente, y consulta el tamaño de la carpeta creada: esa cifra es la que no viaja en el repositorio.