Я хочу развернуть интерфейс Джерси к корневому пути, и я также хочу получить доступ к различным файлам html, css и JS в корневом пути [duplicate]

Способ думать об этом - «думать как компилятор».

Представьте, что вы пишете компилятор. И вы видите такой код.

// file: A.h
class A {
  B _b;
};

// file: B.h
class B {
  A _a;
};

// file main.cc
#include "A.h"
#include "B.h"
int main(...) {
  A a;
}

Когда вы компилируете файл .cc (помните, что .cc, а не .h - это единица компиляции), вам нужно выделить пространство для объекта A. Итак, хорошо, сколько пространства тогда? Достаточно хранить B! Каков размер B? Достаточно хранить A!

Очевидно, что круговая ссылка, которую вы должны сломать.

Вы можете ее разбить, разрешив компилятору зарезервировать столько места, сколько он знает о указателях и ссылках на передний план, для например, всегда будет 32 или 64 бита (в зависимости от архитектуры), и поэтому, если вы замените (или один) указателем или ссылкой, все будет замечательно. Скажем, мы заменим в A:

// file: A.h
class A {
  // both these are fine, so are various const versions of the same.
  B& _b_ref;
  B* _b_ptr;
};

Теперь все лучше. В некотором роде. main() все еще говорит:

// file: main.cc
#include "A.h"  // <-- Houston, we have a problem

#include, для всех экстентов и целей (если вы выберете препроцессор) просто копирует файл в .cc. Так что, .cc выглядит так:

// file: partially_pre_processed_main.cc
class A {
  B& _b_ref;
  B* _b_ptr;
};
#include "B.h"
int main (...) {
  A a;
}

Вы можете понять, почему компилятор не может с этим справиться - он понятия не имеет, что B - он даже не видел символ раньше .

Итак, давайте расскажем компилятору о B. Это известно как декларация вперед и обсуждается далее в этом ответе .

// main.cc
class B;
#include "A.h"
#include "B.h"
int main (...) {
  A a;
}

Это работает . Это не отлично . Но на этом этапе у вас должно быть понимание проблемы с круговой ссылкой и что мы сделали, чтобы «исправить» ее, хотя исправление плохо.

Причина, по которой это исправление плохо, заключается в следующем: f17] должны объявить B, прежде чем они смогут его использовать, и получите ужасную ошибку #include. Итак, давайте переместим декларацию в себя.

// file: A.h
class B;
class A {
  B* _b; // or any of the other variants.
};

И в Bh на данный момент вы можете просто #include "A.h" прямо.

// file: B.h
#include "A.h"
class B {
  // note that this is cool because the compiler knows by this time
  // how much space A will need.
  A _a; 
}

HTH.

19
задан condit 14 September 2012 в 18:03
поделиться

2 ответа

С Джерси 1.x вы должны иметь возможность обслуживать статический контент с одного и того же пути, если вы переключитесь с сервлета Джерси на фильтр. Отбросьте XML-код сервлета, который вы указали, и переключите его на:

<filter>
  <filter-name>Jersey Filter</filter-name>
  <filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>org.frog.jump.JerseyApp</param-value>
  </init-param>
  <init-param>
    <param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
    <param-value>/.*html</param-value>
  </init-param>
</filter> 
<filter-mapping>
  <filter-name>Jersey Filter</filter-name>
  <url-pattern>/*</url-pattern> 
</filter-mapping>

EDIT: в Jersey 2.x вы должны иметь возможность делать то же самое, но имена свойств были изменены. Попробуйте что-то вроде:

<filter>
  <filter-name>Jersey Filter</filter-name>
  <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
  <init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>org.example</param-value>
  </init-param>
  <init-param>
    <param-name>jersey.config.servlet.filter.staticContentRegex</param-name>
    <param-value>/.*html</param-value>
  </init-param>
</filter> 
<filter-mapping>
  <filter-name>Jersey Filter</filter-name>
  <url-pattern>/*</url-pattern> 
</filter-mapping>

И ваш POM должен включать:

<dependency>
  <groupId>org.glassfish.jersey.core</groupId>
  <artifactId>jersey-server</artifactId>
  <version>2.0-m07-1</version>
  <type>jar</type>
  <scope>compile</scope>
</dependency>

<dependency>
  <groupId>org.glassfish.jersey.containers</groupId>
  <artifactId>jersey-container-servlet-core</artifactId>
  <version>2.0-m07-1</version>
  <type>jar</type>
  <scope>compile</scope>
</dependency>

Вам нужно будет настроить регулярное выражение в init-param, если вы хотите использовать css , jsp и т. д.

Еще один хороший вариант - использовать путь с версиями для ваших сервисов («/ v1 / *»), а затем статический контент будет работать без фильтра.

25
ответ дан condit 3 September 2018 в 17:29
поделиться

Вы должны добавить фильтр forwardOn404 для решения этой проблемы

<filter>
    <filter-name>org.glassfish.jersey.examples.bookstore.webapp.MyApplication</filter-name>
    <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>org.glassfish.jersey.examples.bookstore.webapp.MyApplication</param-value>
    </init-param>
    <!-- pass to next filter if Jersey/App returns 404 -->
    <init-param>
        <param-name>jersey.config.servlet.filter.forwardOn404</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

Как сделано в этом примере https://github.com/jersey/jersey/blob/2.17/examples/bookstore -webapp / src / main / webapp / WEB-INF / web.xml

Примечание: убедитесь, что вы изменили конфигурацию <servlet> на конфигурацию <filter>. Джерси ServletContainer является одновременно HttpServlet и a Filter, поэтому вы можете настроить его как в своем web.xml. Чтобы использовать свойство forwardOn404, Джерси нужно настроить как фильтр.

10
ответ дан Paul Samsotha 3 September 2018 в 17:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: