Джерси Guice JSP, как?
Я использую tomcat 6, jersey 1.8 с узором и губкой из трикотажа 3.
У меня проблема с JSP с моей настройкой.
У меня есть сервлет "Статус", который служил в качестве простого сервлета, настроенного с помощью web.xml, сервлета трикотажа, настроенного GuiceFilter, который возвращает ответ jsp view (jsp is/diff/index.jsp), чтобы отобразить результат, как в:
Viewable view = new Viewable("/diff/index.jsp", null);
Response response = Response.ok().entity(view).build();
return response;
Все работает отлично с простым Джерси, как только я пытаюсь использовать его с интеграцией Guice, JSP терпит неудачу, и я получаю ответ 404 с "Запрошенный ресурс (/diff/index.jsp) недоступен."
Используя отладчик, я вижу, что JSPTemplateProcessor называется вызывающим и получил RequestDispatcher со стандартнымWrapper, который имеет "isJspServlet = true" и "jspFile = null".
Файл web.xml выглядит следующим образом:
<servlet>
<display-name>Status Page</display-name>
<servlet-name>Status</servlet-name>
<servlet-class>my.BaseStatusPage</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Status</servlet-name>
<url-pattern>/Status/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/REST/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>my.GuiceServletConfig</listener-class>
</listener>
=====================
GuiceServletConfig:
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new JerseyServletModule() {
@Override
protected void configureServlets() {
bind(DiffPage.class);// the jersey servlet
Map<String, String> params = new HashMap<String, String>();
params.put(PROPERTY_PACKAGES, "my");
params.put(PROPERTY_WEB_PAGE_CONTENT_REGEX, ".*\\.jsp");
params.put(FEATURE_REDIRECT, "true");
params.put(FEATURE_IMPLICIT_VIEWABLES, "true");
params.put(RESOURCE_CONFIG_CLASS, "com.sun.jersey.api.core.PackagesResourceConfig");
serve("/REST/*").with(GuiceContainer.class, params);
}
});
}
=====================
Наличие GuiceContainer в качестве фильтра заставил сервлеты, обслуживаемые из файла web.xml, выйти из строя. Добавление сервлета jsp в web.xml не принесло много пользы.
Btw, я прочитал нить с 25 июля 2010 года в список рассылки jersey, но это не сработало для меня.
Помогите оценить
Спасибо, Eishay
- Приложение -
Я нахожу, что вызываю JSP из кода бизнес-логики. Уродливый, но работает:
protected Response renderJsp(HttpServletRequest request,
HttpServletResponse response, ServletConfig servletConfig) {
request.setAttribute("org.apache.catalina.jsp_file", "/diff/index.jsp");
Class jspServletClazz;
try {
jspServletClazz = forName("org.apache.jasper.servlet.JspServlet");
Object jspServlet = jspServletClazz.getConstructor().newInstance();
jspServletClazz.getMethod("init", ServletConfig.class).invoke(jspServlet,
servletConfig);
jspServletClazz.getMethod("service", HttpServletRequest.class,
HttpServletResponse.class).invoke(jspServlet, request, response);
} catch (Exception e) {
throw new RuntimeException(e);
}
return Response.ok().build();
}
Ответы
Ответ 1
Проблема заключается в настройке Guice на "сервисные запросы" с помощью "сервлета: сервлет" блокирует цепочку запросов и предотвращает передачу запросов, таких как статический контент и вызовы jsp, на обработчики по умолчанию.
Решение состоит в том, чтобы настроить Guice на "фильтрацию" запросов "через" вместо фильтра:
web.xml
<listener>
<listener-class>my.guice.config.package.GuiceServletConfig</listener-class>
</listener>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Обратите внимание, что это конфигурация filter
в отличие от конфигурации servlet
.
GuiceServletConfig
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new JerseyServletModule() {
@Override
protected void configureServlets() {
/* Bindings */
bind(JerseyResource.class);
/* Parameters*/
Map<String, String> params = new HashMap<String, String>();
params.put(JSP_TEMPLATES_BASE_PATH, "/WEB-INF/jsp");
params.put(FEATURE_FILTER_FORWARD_ON_404, "true");
filter("/*").through(GuiceContainer.class, params);
}
});
}
}
Обратите внимание на использование filter().through();
вместо serve().with();
.
Это позволяет передавать статические и jsp-запросы (и включает!) в следующую ссылку в цепочке фильтров и, в конечном итоге, к обработчикам содержимого по умолчанию.
Также обратите внимание на использование выше более поздней опции ServletContainer.FEATURE_FILTER_FORWARD_ON_404
в качестве альтернативы более сложному параметру ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX
, когда вы довольны местоположениями по умолчанию для вашего статического контента.
Вы можете использовать другие параметры, перечисленные в исходном вопросе.
На следующем шаге вы также можете ссылаться на этот вопрос, в частности, с проблемой, с которой я столкнулся с добавлением Guice AOP в эту конфигурацию, чтобы работать вместе с Guice Dependency Injection, Jersey REST Services, статическое содержимое (JavaScript, CSS, изображения) и возврат JSP Viewables.