使用内嵌的Jetty服务器提供静态文件服务

58

我正在尝试使用嵌入式Jetty构建一个简单的演示应用程序,该应用程序从当前工作目录下的“html”子目录中提供静态文件。想法是演示jar和内容的目录可以移动到新位置并仍然正常工作。

我尝试了以下变化,但仍然收到404错误。

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();

更新:以下是Jetty教程中记录的解决方案。正如正确答案所提到的那样,它使用ResourceHandler而不是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();

可以使用以下pom.xml文件:https://code.google.com/p/ram-badger/source/browse/trunk/static-jetty/pom.xml - cwash
1
这似乎无法在Jetty 9上工作... - Ilya Buziuk
1
如果您在使用 Jetty 9 时遇到类似问题,可以参考该链接:https://dev59.com/qofca4cB1Zd3GeqPkpSM - Ilya Buziuk
5个回答

34

1
确实...http://jetty.codehaus.org/jetty/jetty-6/apidocs/org/mortbay/jetty/handler/ResourceHandler.html - Spencer Kormos
4
做到了!谢谢大家!这段代码甚至在Jetty教程中都有。Doh! http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty#Configuring_a_File_Server - HolySamosa
1
如果您需要使用javax.servlet.Filter(有关详细信息,请参见下面的评论),则仍建议使用ServletContextHandler - xorcus
5
当Jetty 6存在的时候,这些建议是有道理的。但是现在使用Jetty 9,这些建议已经不再适用了。参见https://dev59.com/J4fca4cB1Zd3GeqPmbQe#28419106。 - Joakim Erdfelt
第一个链接已经失效了。有人知道如何访问那个页面吗? - The Impaler

21

使用 ResourceHandler 或者 DefaultServlet(和 ServletContextHandler 一起)服务静态内容的方式有一个重要区别。

当一个 ResourceHandler (或者包含多个 ResourceHandler 实例的 HandlerList)被设置为上下文处理器时,它会直接处理请求并忽略任何已注册的 javax.servlet.Filter 实例。

如果你需要过滤器,唯一的方法是使用 ServletContextHandler,向其添加过滤器,然后添加一个 DefaultServlet,最后设置基本的 Resource

基本的 Resource 表示一个 ResourceHandler 将被初始化的 resourceBase 路径。如果从多个目录中提供静态资源,请使用 ResourceCollection(仍然是一个 Resource),并用资源基本字符串数组进行初始化:

ResourceCollection resourceCollection = new ResourceCollection();
resourceCollection.setResources(getArrayOfResourceBaseDirs());

19
在我的小型Web服务器中,我有两个文件,一个是位于/src/webapp下的index.htmlinfo.js。我希望从嵌入式Jetty Web服务器提供它们。这是我解决静态内容问题的方式。
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);

运转得非常好!


2
你能看一下这个问题吗 - https://dev59.com/1Znga4cB1Zd3GeqPf_M2 - Pavel_K

3

我通过在web.xml中添加“css”目录的映射,成功实现了类似的功能。明确告知它使用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>

2
最初的回答:
这是一个Main.java文件:
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;

public class Main
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
        ResourceHandler resource_handler = new ResourceHandler();
        resource_handler.setResourceBase("C:/Users/serge.klimkovitch/Documents/images");
        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
        server.setHandler(handlers);
        server.start();
        server.join();
    }
}

这是 gradle.build 文件:
apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'SheetsQuickstart'
sourceCompatibility = 1.7
targetCompatibility = 1.7
version = '1.0'

repositories {
    mavenCentral()
}

dependencies {
compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.4.16.v20190411'

}

jar {
  manifest {
    attributes(
      'Main-Class': 'SheetsQuickstart'
    )
  }
  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

假设以下文件存在:C:\ Users \ serge.klimkovitch \ Documents \ images \ image.html 。然后,在Eclipse中运行,并在浏览器中转到 http://localhost:8080/image.html 以查看此文件被提供的情况。"最初的回答"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接