Как обслуживать статический контент с помощью JAX-RS?

У меня есть самообслуживаемая служба JAX-RS REST, реализованная с расширением Restore JAX-RS.

Теперь я должен обслуживать статический контент, и мне было интересно, как это сделать с JAX-RS. Обратите внимание, что я не знаю структуру физического каталога во время компиляции. Итак, учитывая URL-адрес, например

http://bla-bla:8182/static/yaba/daba/doo.png

должен возвращаться файл $(ROOT)/yaba/daba/doo.png, где $(ROOT) - это корневой каталог статического содержимого.

Можно ли это сделать с чистым JAX-RS?

Спасибо.

ИЗМЕНИТЬ

Известно во время компиляции:

  • Путь к файловой системе в корневой папке статического содержимого
  • URL-адрес HTTP, используемый для ссылки на корневую папку статического содержимого

Неизвестно во время компиляции:

  • Фактическое содержимое корневой папки - количество файлов, типов файлов, структуры каталогов.

Ответ 1

Просто нашел его.

В соответствии с javadocs аннотации javax.ws.rs.Path можно указать регулярное выражение, чтобы указать, что считается совпадением параметров шаблона.

Следовательно, работает следующий код:

@Path("static")
public class StaticContentHandler {
  ...
  @GET
  @Path("{path:.*}")
  public FileRepresentation Get(@PathParam("path") String path) {
    ...;
  }
}

GET http://localhost:8182/static/yaba/daba/doo.png достигает метода Get с path равным "yaba/daba/doo.png" - именно то, что я искал.

Надеюсь, это поможет кому угодно.

BTW, FileRepresentation принадлежит Restlet, поэтому действительно чистая реализация JAX-RS вернет здесь что-то еще.

Ответ 2

Предполагая, что статическая папка находится здесь: ./src/main/resources/WEB-INF/static в вашем проекте:

@Path("")
public class StaticResourcesResource {

  @Inject ServletContext context;

  @GET
  @Path("{path: ^static\\/.*}")
  public Response staticResources(@PathParam("path") final String path) {

    InputStream resource = context.getResourceAsStream(String.format("/WEB-INF/%s", path));

    return Objects.isNull(resource)
        ? Response.status(NOT_FOUND).build()
        : Response.ok().entity(resource).build();
  }
}

Вот полное описание с практическими примерами и хранилищем: https://daggerok.github.io/thymeleaf-ee/#configure-jax-rs-serve-static-files-and-webjars

Ответ 3

Вы можете сделать это с помощью чистого JAX-RS, реализовав соответствующие ресурсы: в основном вам просто нужно отправить массив байтов, а JAX-RS уже включает в себя провайдера Byte Array для любого типа носителя.

Проблема в том, что ваша реализация, вероятно, будет менее эффективной, чем стандартные реализации веб-серверов. Обычно лучше всего поставить статический контент на веб-сервер, например Apache HTTPD или IIS или даже Tomcat.