java - Jersey Guice JSP如何?

标签 java jsp jersey guice

我正在使用带有 jersey guice 和 guice 3 的 tomcat 6、jersey 1.8。 我在设置中使用 JSP 时遇到问题。 我有一个“状态”servlet,它是一个由 web.xml 配置的简单 servlet,一个由 GuiceFilter 配置的 jersey servlet,它返回一个 jsp View 响应(jsp 是/diff/index.jsp)以呈现结果,如下所示:

Viewable view = new Viewable("/diff/index.jsp", null); 
Response response = Response.ok().entity(view).build(); 
return response;

这一切都与简单的 Jersey 完美配合,一旦我尝试将它与 Guice 集成,JSP 就会失败,并且我会收到 404 响应“请求的资源 (/diff/index.jsp) 不可用。 "

使用调试器,我可以看到调用的 JSPTemplateProcessor 并获得了一个带有 StandardWrapper 的 RequestDispatcher,该 StandardWrapper 具有“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>

======================

GuiceServlet 配置:

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 提供的 servlet 失败。在 web.xml 中添加一个 jsp servlet 并没有什么好处。

顺便说一句,我在 the jersey mailing list 上阅读了 2010 年 7 月 25 日的帖子。但这对我不起作用。

帮助表示赞赏 谢谢,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();
  }

最佳答案

问题是由于将 Guice 配置为“使用”Servlet“服务”请求:Servlet 阻塞了请求链并阻止诸如静态内容和 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 选项的替代方案,以便您对默认设置感到满意静态内容的位置。

您仍然可以使用原始问题中列出的其他选项。

下一步,您还可以refer to this question特别涉及我在此配置中添加 Guice AOP 以与 Guice 依赖注入(inject)、Jersey REST 服务、静态内容(JavaScript、CSS、图像)一起使用并返回 JSP 可视项时遇到的问题。

关于java - Jersey Guice JSP如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7198872/

相关文章:

java - 无法绑定(bind) ConnectionPoolDataSource 实例

java - Spring 3.1 entityManagerFactory java.lang.NoSuchFieldError : NULL Error

java - 尝试删除用户定义的双向链表中特定位置的元素

java - JSP 视频流(使用 Servlet)

java - 如何使用 Jackson 序列化声明性链接( Jersey )

java - 使用 ScrolledComposite 的 setOrigin 方法

java - bean :message equivalent in java code?

javascript - 无法在包含的jsp中获取jSTL变量

xml - Web 服务响应的 text/xml 与 application/xml 之间有什么区别

java - CXF Rest 服务的 Jersey 客户端问题