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.
- 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».
- 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.
- Elige la entidad principal y describe sus cuatro operaciones CRUD con tus palabras: registrar un préstamo, consultarlo, corregirlo y eliminar un registro equivocado.
- 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.
- 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.
- 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
- 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.
- Escribe los siguientes comandos, uno cada vez, y pulsa Intro después de cada uno:
java -version
javac -version
git --version
- Comprueba que
javayjavacmuestran Java 21 o una versión compatible posterior.javaces el compilador: si solo funcionajava, 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. - 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.
- Pulsa Ctrl+Shift+X (en macOS, Cmd+Shift+X) o el icono de las piezas de puzle en la barra lateral.
- 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.
- Busca Spring Boot Extension Pack y pulsa Install. Añade el autocompletado de
application.propertiesy el panel desde el que se arrancan las aplicaciones Spring. - 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.
- 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.
- Pulsa Generate. El navegador descarga un ZIP con el nombre del artefacto.
- Extrae el ZIP en la carpeta de trabajo. No abras el código dentro del ZIP.
- En el IDE elige Abrir carpeta/proyecto y selecciona la carpeta que contiene
pom.xml, no la carpetasrc. 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
gestordentro. É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
- Abre la terminal del IDE en la carpeta de
pom.xml. Comprueba su ubicación conpwdy lista los archivos conls; ambos comandos funcionan también en PowerShell. Si no vespom.xml, cambia a la carpeta correcta antes de seguir. - 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.
- Espera a que aparezcan mensajes que contengan
Tomcat started on port 8080yStarted GestorApplication. El texto alrededor puede variar. La terminal queda ocupada porque el servidor sigue funcionando: no es un bloqueo. - Abre
http://localhost:8080/en el navegador. Aparecerá una respuesta de error, normalmente una página Whitelabel Error Page con estado404. 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.
- En
src/main/java/com/ejemplo/gestor, crea la carpeta o paquetecontrollerdesde el IDE. Dentro crea la claseHolaController. Su archivo debe quedar ensrc/main/java/com/ejemplo/gestor/controller/HolaController.java. - 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.";
}
}
- Relaciona cada parte con su función:
packagecoincide con la ubicación; losimportpermiten usar las anotaciones;@RestControllerindica que los resultados de los métodos se envían como respuesta;@GetMapping("/hola")asocia un GET a esa ruta;returnproporciona el cuerpo de la respuesta. El nombre del método Java no determina la URL. - 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.
- Abre
http://localhost:8080/hola. Debes leer exactamente la frase dereturn. - 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.
- Con
/holaabierto, pulsa F12 o abre el menú del navegador → Herramientas de desarrollo. Elige la pestaña Red o Network. - 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.
- Pulsa la fila cuya dirección acaba en
/hola. Puede aparecer ademásfavicon.ico, el icono de la pestaña: no es nuestra petición y puedes ignorarlo. - En Cabeceras/Headers, busca URL, método
GETy estado200. LocalizaContent-Typeentre las cabeceras de respuesta: describe el tipo de contenido. En Respuesta/Response, lee el texto de tu método. - Abre
/ruta-que-no-existe, selecciona su fila y observa el404. 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/holapara 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
- En
HolaController, debajo del métodoholay 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";
}
- Cambia
prestamosy 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. - 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.
- En la carpeta de
pom.xml, crea el archivoREADME.md. El generador no lo incluye: entrega unHELP.mdcon enlaces a la documentación que su propio.gitignoreexcluye del repositorio. Escribe en el README la propuesta del paso 1, el comando de arranque y tus tres rutas. - 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.
- Abre
.gitignore, el archivo que indica a Git qué no debe subir. Comprueba que excluyetarget/(archivos generados al compilar), la configuración local del IDE y.envsi lo utilizas más adelante. Conserva los archivos del wrapper, incluidos.mvn/,mvnwymvnw.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.
- 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. - Antes de ejecutar nada, inspecciona la copia. No existe
target/ni ninguna biblioteca: solo el código, elpom.xmly el wrapper. - Abre la carpeta en el editor y espera a que termine de importar el proyecto Maven. Si los
importaparecen 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 elpom.xml. - Arranca con el wrapper y comprueba que
/holaresponde el mismo texto que en tu carpeta original. - Ejecuta
git statusen la copia. Pese a haber compilado,target/no aparece como cambio pendiente: el.gitignorelo 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.