无法使用嵌入式 Jetty 访问 JAR 文件中的静态资源
Unable to access static resources in JAR file using embedded Jetty
我的问题和这个问题基本一样:
Setting Jetty resourcebase to static file embedded in the same jar file
我正在使用嵌入式 Jetty,我想访问同一个 JAR 文件中的一些静态 HTML 文件。
Jetty 服务器的设置方式如下:
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
String res = ApiServer.class.getClassLoader().getResource("res").toExternalForm();
context.setResourceBase(res);
jettyServer = new Server(port);
jettyServer.setHandler(context);
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
String classes = new StringJoiner(",")
.add(MyClass1.class.getCanonicalName())
.add(MyClass2.class.getCanonicalName())
.toString();
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, classes);
JAR 的文件夹结构是这样的:
root
| src (Java classes in here)
| res
| index.html
然而,它就是行不通。我尝试以各种方式访问 URL:
http://localhost:12345/res/index.html
或
http://localhost:12345/index.html
但都不起作用。
我做错了什么?
您拥有的代码...
String res = ApiServer.class.getClassLoader().getResource("res").toExternalForm();
context.setResourceBase(res);
对我不起作用,因为您不能使用类加载器获取目录引用,只能获取文件引用。调用 ClassLoader.getResource("res")
总是 returns null。
这需要先解决。
接下来,你的泽西岛申报太贪心了。
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
这意味着 Servlet (ServletContainer.class
) 正在处理 100% 的所有请求,甚至是对静态内容的请求。
根据您的 url-pattern,Servlet 不可能 "not handle" 静态请求并让 Jetty 为这些静态请求提供服务。
放松这个url-pattern,说/api/*
然后你会更近一步。
您需要的最后一件事是 DefaultServlet
(Servlet 规范中的组件,以及提供静态文件的 Jetty)。
所以您将得到以下代码...
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
URL url = ApiServer.class.getClassLoader().getResource("res/index.html");
if (url == null)
throw new FileNotFoundException("Whoops, can't find static resources folder");
URI webroot = url.toURI().resolve("./");
context.setBaseResource(Resource.newResource(webroot));
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/api/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
String classes = new StringJoiner(",")
.add(MyClass1.class.getCanonicalName())
.add(MyClass2.class.getCanonicalName())
.toString();
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, classes);
// always named "default", always last, always on url-pattern "/"
ServletHolder defaultServ = new ServletHolder("default", DefaultServlet.class);
defaultServ.setInitParameter("dirAllowed","true");
context.addServlet(defaultServ,"/");
jettyServer = new Server(port);
jettyServer.setHandler(context);
我的问题和这个问题基本一样:
Setting Jetty resourcebase to static file embedded in the same jar file
我正在使用嵌入式 Jetty,我想访问同一个 JAR 文件中的一些静态 HTML 文件。
Jetty 服务器的设置方式如下:
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
String res = ApiServer.class.getClassLoader().getResource("res").toExternalForm();
context.setResourceBase(res);
jettyServer = new Server(port);
jettyServer.setHandler(context);
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
String classes = new StringJoiner(",")
.add(MyClass1.class.getCanonicalName())
.add(MyClass2.class.getCanonicalName())
.toString();
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, classes);
JAR 的文件夹结构是这样的:
root
| src (Java classes in here)
| res
| index.html
然而,它就是行不通。我尝试以各种方式访问 URL:
http://localhost:12345/res/index.html
或
http://localhost:12345/index.html
但都不起作用。
我做错了什么?
您拥有的代码...
String res = ApiServer.class.getClassLoader().getResource("res").toExternalForm();
context.setResourceBase(res);
对我不起作用,因为您不能使用类加载器获取目录引用,只能获取文件引用。调用 ClassLoader.getResource("res")
总是 returns null。
这需要先解决。
接下来,你的泽西岛申报太贪心了。
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
这意味着 Servlet (ServletContainer.class
) 正在处理 100% 的所有请求,甚至是对静态内容的请求。
根据您的 url-pattern,Servlet 不可能 "not handle" 静态请求并让 Jetty 为这些静态请求提供服务。
放松这个url-pattern,说/api/*
然后你会更近一步。
您需要的最后一件事是 DefaultServlet
(Servlet 规范中的组件,以及提供静态文件的 Jetty)。
所以您将得到以下代码...
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
URL url = ApiServer.class.getClassLoader().getResource("res/index.html");
if (url == null)
throw new FileNotFoundException("Whoops, can't find static resources folder");
URI webroot = url.toURI().resolve("./");
context.setBaseResource(Resource.newResource(webroot));
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/api/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
String classes = new StringJoiner(",")
.add(MyClass1.class.getCanonicalName())
.add(MyClass2.class.getCanonicalName())
.toString();
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, classes);
// always named "default", always last, always on url-pattern "/"
ServletHolder defaultServ = new ServletHolder("default", DefaultServlet.class);
defaultServ.setInitParameter("dirAllowed","true");
context.addServlet(defaultServ,"/");
jettyServer = new Server(port);
jettyServer.setHandler(context);