Jersey Guice JSP怎么样?

Eis*_*ith 21 java jsp jersey guice

我正在使用tomcat 6,jersey 1.8 with jersey guice and guice 3.我在设置时使用JSP时遇到问题.我有一个"Status"servlet作为web.xml配置的简单servlet,一个由GuiceFilter配置的jersey servlet,它返回一个jsp视图响应(jsp是/diff/index.jsp),用于呈现结果,如下所示:

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

这一切都与简单的泽西岛完美配合,一旦我试图用Guice集成它,JSP失败了,我得到了404响应,"请求的资源(/diff/index.jsp)不可用."

使用调试器,我可以看到JSPTemplateProcessor被调用,并获得了一个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>
Run Code Online (Sandbox Code Playgroud)

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

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); 
      } 
    }); 
  } 
Run Code Online (Sandbox Code Playgroud)

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

将GuiceContainer作为过滤器使得从web.xml提供的servlet失败.在web.xml中添加一个jsp servlet没有太大作用.

顺便说一句,我已经从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();
  }
Run Code Online (Sandbox Code Playgroud)

Kyn*_*nth 5

问题是由于将 Guice 配置为“使用”一个 Servlet 来“服务”请求:Servlet 会阻塞请求链并阻止诸如静态内容和 jsp 调用之类的请求被传递到默认处理程序。

解决方案是将 Guice 配置为“通过”过滤器“过滤”请求:

网页.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>
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个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);
            } 
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

注意使用filter().through();代替serve().with();

这允许将静态和 jsp 请求(和包含!)传递到过滤器链中的下一个链接,并最终传递到默认的内容处理程序。

另请注意,当您对静态内容的默认位置感到满意时,上面使用较新的ServletContainer.FEATURE_FILTER_FORWARD_ON_404选项可以替代更复杂的ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX选项。

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

对于下一步,您还可以参考这个问题,具体涉及我在将 Guice AOP 添加到此配置中以与 Guice 依赖注入、Jersey REST 服务、静态内容(JavaScript、CSS、图像)和返回 JSP 可视项一起工作时遇到的问题。