Невозможно получить доступ к статическим ресурсам в файле JAR, используя встроенную Jetty - PullRequest
0 голосов
/ 21 июня 2019

У меня в основном та же проблема, что и у этого вопроса:

Установка для базы ресурсов Jetty статического файла, встроенного в тот же файл jar

, где я использую встроенную Jetty и хочу получить доступ к некоторым статическим HTML-файлам в том же файле JAR.

Вот как настроен сервер 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

но ни один не работает.

Что я делаю не так?

1 Ответ

1 голос
/ 18 июля 2019

код у вас есть ...

String res = ApiServer.class.getClassLoader().getResource("res").toExternalForm();
context.setResourceBase(res);

У меня не работает, так как вы не можете использовать загрузчик классов для получения ссылки на каталог, только ссылки на файлы. Вызов ClassLoader.getResource("res") всегда возвращает ноль.

Это нужно исправить в первую очередь.

Далее, ваше заявление о Джерси чрезвычайно жадное.

ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);

Это означает, что сервлет (ServletContainer.class) обрабатывает 100% всех запросов, даже запросов на статическое содержимое.

Невозможно, чтобы этот сервлет, основываясь на вашем шаблоне url, "не обрабатывал" статические запросы и позволял Jetty обслуживать эти статические запросы.

Расслабьте этот шаблон URL, скажем /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);
...