JxMVC 3.5.1 · Jakarta EE 10 · Java 17+
El framework MVC para Jakarta EE que es seguro por defecto y no trae dependencias.
Un solo JAR de 298 KB con routing, acceso a datos, pool de conexiones, JSON, caché, tareas programadas, WebSocket, OpenAPI, OpenID Connect y lectura de PDF. Las protecciones se aplican en cada petición, antes de tu código, sin módulos adicionales.
curl -fsSL https://raw.githubusercontent.com/Andre031222/jxmvc/main/install.sh | sh -s -- new mi-app
Instala el core en tu repositorio Maven y crea un proyecto. En Windows usa el comando de PowerShell de Descargas.
@JxControllerMapping("notes") public class NoteController extends JxController { @JxGetMapping("/{id}") public ActionResult show() { try (JxDB db = db()) { return json(db.queryRow("SELECT * FROM note WHERE id = ?", model.pathVarLong("id"))); } } @JxRequireAuth @JxPostMapping("/") public ActionResult create(@JxValid @JxBody Note note) { long id = new NoteRepository().save(note); return redirect("/notes/" + id); } } public class Note { @JxId public Long id; @JxRequired @JxMaxLength(200) public String title; }
Seguridad por defecto
Protegido antes de escribir la primera línea.
Una regla decide qué viene activo: una protección está encendida si es correcta para cualquier aplicación, y es opcional si depende de cómo se despliega. Por eso las cabeceras, el rechazo de peticiones de otro origen o el límite del cuerpo están siempre, y el límite de peticiones o el token de sesión se activan con una anotación o una propiedad.
Relajar una protección es siempre una decisión explícita y local.
| Activo por defecto | Opcional |
|---|---|
nosniff, Referrer-Policy, X-Frame-Options y una CSP mínima en cada respuesta | CSP completa (jxmvc.security.csp); HSTS bajo HTTPS |
Rechazo de peticiones cuyo Origin es otro host | Acceso entre orígenes por ruta (@JxCors) |
Sanitización de parámetros; cuerpo máximo de 10 MB (413); JSON estricto con profundidad 64 (400) | Token de sesión contra CSRF (jxmvc.security.csrf) |
Autenticación que falla cerrada en @JxRequireAuth; sin detalles de excepciones en producción | Límite de peticiones por acción (@JxRateLimit) |
Redirecciones solo al mismo sitio; endpoints internos /jx/* ocultos en producción | Redirecciones externas (jxmvc.redirect.external); proxies de confianza (jxmvc.trustProxy) |
Evaluación medida
Comparado con Spring Boot, Quarkus, Micronaut y Javalin.
La misma aplicación mínima en los cinco frameworks, en su configuración por defecto, sobre Linux sin virtualizar con el mismo heap fijo de 512 MB. 120.9 millones de peticiones sin errores.
Ataques bloqueados por defecto
de 18 pruebas automáticas; mayor es mejor
Librerías en producción
aplicación mínima, framework y servidor incluidos; menor es mejor
Arranque en frío
hasta la primera respuesta 200, en JVM; menor es mejor
Throughput en /json
miles de peticiones por segundo, 64 conexiones; mayor es mejor
El precio es el throughput: entre 5 y 15 % menos en endpoints mínimos, una diferencia que se reduce cuando la petición consulta una base de datos. Imagen de contenedor más pequeña del grupo (274 MB) y memoria residente en la mitad del grupo (461 MB). Datos crudos, scripts y entorno en benchmarks/ y en Zenodo.
Pipeline
Quince etapas, siempre en el mismo orden.
Un único servlet atiende cada petición. La compuerta de seguridad va antes del controlador, así que ningún código que escribas, o que olvides escribir, puede saltarla.
Entrada
- Endpoints internos
- Inicio de métricas
- Resolución de la ruta
Compuerta de seguridad
- Límite de peticiones
- Autenticación y roles
- Token CSRF
- Política de origen
Preparación
- Contexto de la petición
- Filtros globales
- Controlador y servicios
- Hooks previos
Ejecución
- Acción, transacción o async
- Hooks posteriores
- Renderizado
- Registro de métricas
Alrededor de todas las etapas el servlet pone las cabeceras de seguridad y comprime la respuesta.
Incluido en el core
Todo lo que una aplicación real necesita.
Routing
Anotaciones, plantillas con variables y convención /controlador/accion/args. 405 cuando el método no existe.
Datos
JxDB con parámetros con nombre, filas sin reflexión, repositorio genérico con paginación y borrado lógico, transacciones.
Pool de conexiones
JxPool con revalidación configurable. PostgreSQL, MySQL, SQL Server y cualquier driver JDBC.
JSON estricto
Parser RFC 8259 propio con límites de entrada; responde 400 ante documentos truncados o mal formados.
Validación
@JxValid con @JxRequired, @JxMaxLength y demás restricciones sobre el cuerpo.
OpenID Connect
Flujo de código con PKCE y verificación RS256 del token usando solo el JDK. Rechaza none.
Contraseñas
JxPasswords: PBKDF2-SHA256 con sal aleatoria y verificación en tiempo constante.
Caché, tareas y eventos
Caché en memoria con expiración, cron, tareas a intervalo y un bus de eventos síncrono.
WebSocket
Endpoints con salas y difusión. Hilos virtuales en Java 21 o superior.
JxPdf extrae texto y metadatos, incluso de documentos cifrados, detecta páginas escaneadas y genera PDF simples.
Observabilidad
/jx/health siempre; /jx/info, /jx/metrics y /jx/openapi en desarrollo o con jxmvc.internal.expose.
Pruebas sin librerías
Un runner propio y peticiones simuladas para probar controladores sin contenedor ni JUnit.
Código y citación
Abierto, archivado y citable.
El código, las aplicaciones de comparación, los dos arneses de evaluación y los datos crudos están en GitHub bajo licencia MIT. Cada versión queda archivada en Zenodo con su propio DOI.
| Recurso | Enlace |
|---|---|
| Repositorio | github.com/Andre031222/jxmvc |
| DOI de todas las versiones | 10.5281/zenodo.21896136 |
| DOI de la versión 3.5.1 (con los datos finales) | 10.5281/zenodo.23604453 |
| DOI de la versión 3.5.0 (código evaluado) | 10.5281/zenodo.23585853 |
| Datos y arneses | benchmarks/ |
Del cero a Tomcat en dos comandos.
El instalador descarga la última versión, instala el core en tu repositorio Maven y crea el proyecto. mvn package cargo:run descarga Tomcat y lo levanta.