En vivo · versión en desarrollo

Una aplicación web completa en un solo jar.

Esta página la sirve JxServer, el servidor HTTP/1.1 y HTTPS de JxMVC escrito sobre el JDK. Sin Tomcat, sin contenedor de servlets y sin librerías de terceros: el jar contiene el sitio y jxmvc-core, nada más.

$java -jar jxmvc-native.jar
  • HTTP/1.1
  • TLS 1.2 y 1.3
  • WebSocket RFC 6455
  • PDF con firma CMS
  • Hilos virtuales
~450 KBla aplicación entera
0librerías de terceros
…de memoria en uso ahora
1proceso, sin contenedor

Pruébalo

Tres cosas que antes pedían librerías.

Todo lo de esta sección lo resuelve el mismo proceso Java que sirve la página.

Chat por WebSocket

Abre esta página en otra pestaña o en tu celular y escribe en la misma sala.

desconectado
  • Pulsa «Unirse» para conectarte.

PDF generado y firmado

JxPdf incrusta una fuente TTF y firma con CMS usando solo el JDK.

Seguro por defecto

Las cabeceras que llegaron a tu navegador.

Esta lista se lee en vivo de la última respuesta del servidor. JxServer además rechaza peticiones mal formadas o ambiguas antes de que lleguen a la aplicación.

  • Petición sin Host o con Content-Length y Transfer-Encoding a la vez: 400
  • Cabeceras demasiado grandes: 431 · cuerpo demasiado grande: 413
  • Cliente lento que no termina las cabeceras: conexión cerrada
  • WebSocket desde otro origen: 403
  • Rutas con .. o archivos ocultos: no se sirven
CabeceraValor recibido
Cargando…

El código

Lo que hay detrás de esta página.

Dos clases Java, un archivo de propiedades y los estáticos en src/main/resources/static.

@JxControllerMapping("api")
public class ApiController extends JxController {

    @JxGetMapping("estado")
    public ActionResult estado() {
        return json(Map.of("servidor", "JxServer", "version", JxPipeline.VERSION));
    }

    @JxGetMapping("pdf")
    public ActionResult pdf() throws Exception {
        JxPdf pdf = new JxPdf();
        pdf.AddFont("Bricolage", fuente);
        pdf.SetFont("Bricolage", 22);
        pdf.TextXY(40, 52, "Documento generado por JxServer");
        pdf.Sign(firmante, "Demostración", "https.jxmvc.ginit.dev");
        view.inline(pdf.GetStream(), "application/pdf", "jxserver.pdf");
        return null;
    }
}
@JxWsEndpoint("/ws/chat/{sala}")
public class ChatSocket extends JxWebSocket {

    @Override
    protected void onOpen(Peer peer, String... vars) {
        joinRoom(vars[0], peer);
    }

    @Override
    protected void onMessage(Peer peer, String texto) {
        broadcast((String) peer.attributes().get("sala"), texto);
    }
}
jxmvc.controllers.package = jxmvc.controllers
jxmvc.server.port         = 8094
jxmvc.server.https.port   = 8444
jxmvc.server.keystore     = tls.p12
jxmvc.security.hsts       = true
$ mvn package
$ java -jar target/jxmvc-native.jar
JxServer escuchando http:8094 https:8444

Números

JxServer frente a Tomcat, con la misma aplicación.

Medición preliminar en una sola máquina: servidor en 4 núcleos, heap de 512 MB, 64 conexiones, 3 repeticiones de 15 segundos. La evaluación formal está en curso.