Alba es un framework minimalista diseñado para crear servidores web en Java. Ofrece una API sencilla y flexible para gestionar rutas, middlewares y respuestas HTTP. Este framework está inspirado en herramientas populares como Hono.js y Express.js, pero con un enfoque ligero y minimalista, ideal para aprender cómo funcionan los servidores web desde cero.
Para agregar Alba a tu proyecto, puedes utilizar Maven o Gradle.
Agrega la siguiente dependencia en el archivo pom.xml
:
<dependency>
<groupId>io.github.angel-raa</groupId>
<artifactId>alba</artifactId>
<version>1.0-0</version>
</dependency>
Incluye la siguiente línea en el archivo build.gradle
:
implementation group: 'io.github.angel-raa', name: 'alba', version: '1.0-0'
Alba ahora incluye soporte nativo para Thymeleaf, Las plantillas deben almacenarse en la carpeta resources/templates/
y se configuran mediante el archivo alba.properties
.
# Configuración del Motor de Plantillas
alba.template.engine=thymeleaf
alba.template.cache=true
alba.template.prefix=templates/
alba.template.suffix=.html
- alba.template.engine: Especifica el motor de plantillas a usar (en este caso,
thymeleaf
). - alba.template.cache: Habilita o deshabilita el caché de plantillas.
- alba.template.prefix: Prefijo para la ubicación de las plantillas (carpeta
templates/
). - alba.template.suffix: Sufijo para los archivos de plantilla (.html).
Puedes usar Thymeleaf en métodos de clase anotados con @Get
, @Post
, etc. Aquí tienes un ejemplo:
@Get("/home")
public Response getHome(Request request) {
Map<String, Object> model = new HashMap<>();
model.put("title", "Bienvenido a Alba");
model.put("message", "¡Hola desde Thymeleaf!");
return new Response().addTemplate("index.html", model);
}
- Se crea un modelo (
Map<String, Object>
) con datos dinámicos (title
ymessage
). - La plantilla
index.html
se procesa con el modelo y se devuelve como respuesta.
También puedes usar funciones lambda para manejar rutas y devolver plantillas:
server.get("/hello", res -> {
Map<String, Object> model = new HashMap<>();
model.put("title", "Hola Mundo");
model.put("message", "Este es un ejemplo de función lambda con Thymeleaf.");
Response response = new Response(200, null);
response.addTemplate("index.html", model);
return response;
});
- La ruta
/hello
devuelve una página HTML generada dinámicamente con Thymeleaf. - El modelo contiene los datos que se inyectan en la plantilla.
Las plantillas deben almacenarse en la carpeta resources/templates/
. Por ejemplo:
src/
├── main/
│ ├── resources/
│ │ ├── templates/
│ │ │ └── index.html
Aquí tienes un ejemplo de una plantilla Thymeleaf:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="${title}">Título por defecto</title>
</head>
<body>
<h1 th:text="${message}">Mensaje por defecto</h1>
</body>
</html>
${title}
y${message}
son variables del modelo que se inyectan en la plantilla.- Si no se proporciona un valor para estas variables, se mostrarán los valores por defecto.
El método addTemplate
permite renderizar una plantilla con un modelo y devolverla como respuesta.
public Response addTemplate(String templateName, Map<String, Object> model) {
if (templateName == null || templateName.isEmpty()) {
throw new IllegalArgumentException("El nombre de la plantilla no puede ser nulo o vacío");
}
addHeader("Content-Type", "text/html; charset=UTF-8");
this.body = templateProcessor.render(templateName, model);
return this;
}
- templateName: Nombre de la plantilla (sin prefijo ni sufijo).
- model: Datos a inyectar en la plantilla.
Este middleware permite configurar políticas de acceso entre dominios (Cross-Origin Resource Sharing).
CorsMiddleware corsMiddleware = new CorsMiddleware();
corsMiddleware.addAllowedOrigins("https://example.com")
.addAllowedMethods("GET", "POST")
.setAllowCredentials(true)
.setMaxAge(3600);
server.use(corsMiddleware);
- Permite configurar orígenes permitidos, métodos HTTP y credenciales.
Restringe el acceso a ciertas rutas o al servidor completo basándose en las direcciones IP de los clientes.
IpRestrictionMiddleware ipRestrictionMiddleware = new IpRestrictionMiddleware()
.addAllowedIps(Arrays.asList("192.168.1.10", "192.168.1.20"))
.addBlockedIps(Collections.singletonList("192.168.1.15"))
.setAllowAllByDefault(false); // Bloquea todas las IPs por defecto
server.use(ipRestrictionMiddleware);
- Permite crear una lista blanca y negra de IPs.
Detecta el idioma preferido del cliente (basado en el encabezado Accept-Language
) y configura el idioma de la aplicación en función de eso.
LanguageMiddleware languageMiddleware = new LanguageMiddleware()
.addSupportedLanguages(Set.of("es", "en", "fr"))
.setDefaultLanguage("en")
.setLanguageHeader("Accept-Language");
server.use(languageMiddleware);
- Detecta automáticamente el idioma preferido del cliente.
El middleware CSRF protege contra ataques de falsificación de solicitudes entre sitios. Valida tokens CSRF en solicitudes POST, PUT y DELETE.
Server server = new Server();
server.use(new CsrfMiddleware()); // Habilitar protección CSRF
server.start();
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Formulario</title>
</head>
<body>
<form action="/submit" method="post" csrf>
<input type="text" name="username" placeholder="Nombre de usuario" />
<button type="submit">Enviar</button>
</form>
</body>
</html>
Si el token es inválido, la solicitud será rechazada con 403 Forbidden.
Ahora puedes agrupar rutas relacionadas bajo un prefijo común para reducir la repetición de código.
server.route("/api/v1/posts", new PostController());
Aquí tienes un ejemplo completo que utiliza todas las nuevas funcionalidades del framework:
import server.Server;
import middleware.CorsMiddleware;
import middleware.IpRestrictionMiddleware;
import middleware.LanguageMiddleware;
public class Main {
public static void main(String[] args) {
Server server = new Server(8080);
// Middleware CORS
server.use(new CorsMiddleware().addAllowedOrigins("https://example.com"));
// Middleware Restricción IPs
server.use(new IpRestrictionMiddleware().addAllowedIps(Arrays.asList("192.168.1.10")));
// Middleware Idioma
server.use(new LanguageMiddleware().setDefaultLanguage("en"));
// Rutas agrupadas
server.route("/api/v1/posts", new PostController());
// Ruta simple
server.get("/", request -> new Response(200, new JSONObject().put("message", "Welcome")));
server.start();
}
}
public class Main {
public static void main(String[] args) throws IOException {
Server server = new Server(8080);
server.get("/user/:id", request -> {
String userId = request.getPathParam("id");
return new Response(200, new JSONObject().put("userId", userId));
});
server.start();
}
}
- GET
- POST
- PUT
- DELETE
Este proyecto está bajo la licencia MIT. Consulta el archivo LICENSE para más detalles.