java - Servir archivos estáticos con Jetty incrustado
embedded-jetty (4)
Estoy intentando crear una aplicación de demostración simple con Jetty incrustado que sirva archivos estáticos desde un directorio "html" que es un subdirectorio del directorio de trabajo actual. La idea es que el directorio con el demo jar y el contenido se puedan mover a una nueva ubicación y seguir funcionando.
He intentado variaciones de lo siguiente, pero sigo obteniendo 404s.
ServletContextHandler context =
new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.getInitParams().put(
"org.eclipse.jetty.servlet.Default.resourceBase", "html");
context.addServlet(new ServletHolder(new DefaultServlet()), "/html");
Server jetty = new Server(8080);
jetty.setHandler(context);
jetty.start();
Actualización: Aquí hay una solución como se documenta en el tutorial de Jetty. Como se mencionó en la respuesta correcta, usa un ResourceHandler
lugar de un ServletContextHandler
:
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(8080);
server.addConnector(connector);
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[]{ "index.html" });
resource_handler.setResourceBase(".");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
server.start();
server.join();
En mi pequeño servidor web tengo dos archivos, un index.html
y un info.js
localizados en /src/webapp
y quiero que se sirvan desde el servidor web incorporado de Jetty.
Así es como soluciono el problema con contenido estático.
Server server = new Server(8080);
ServletContextHandler ctx = new ServletContextHandler();
ctx.setContextPath("/");
DefaultServlet defaultServlet = new DefaultServlet();
ServletHolder holderPwd = new ServletHolder("default", defaultServlet);
holderPwd.setInitParameter("resourceBase", "./src/webapp/");
ctx.addServlet(holderPwd, "/*");
ctx.addServlet(InfoServiceSocketServlet.class, "/info");
server.setHandler(ctx);
¡Trabajado como un encanto!
Hay una diferencia importante entre servir contenido estático usando un ResourceHandler
y usar un DefaultServlet
(con un ServletContextHandler
).
Cuando un ResourceHandler
(o un HandlerList
contiene varias instancias de ResourceHandler
) se configura como un controlador de contexto, procesa directamente las solicitudes e ignora cualquier instancia registrada de javax.servlet.Filter.
Si necesita filtros, la única forma de hacerlo es utilizando un ServletContextHandler
, agregándole filtros, luego agregando un DefaultServlet
y, por último, configurando el Resource
base.
El Resource
base representa una ruta de base de ResourceHandler
que se inicializaría un ResourceHandler
. Si está sirviendo recursos estáticos de varios directorios, use un ResourceCollection
(que todavía es un Resource
) e inicialícelo con una matriz de cadenas de recursos:
ResourceCollection resourceCollection = new ResourceCollection();
resourceCollection.setResources(getArrayOfResourceBaseDirs());
Logré lograr algo similar agregando una asignación para el directorio "css" en web.xml. Le digo explícitamente que use DefaultServlet:
<servlet>
<servlet-name>DefaultServlet</servlet-name>
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DefaultServlet</servlet-name>
<url-pattern>/css/*</url-pattern>
</servlet-mapping>
Utilice un ResourceHandler
lugar de ServletContextHandler
.