泽西吉斯JSP如何?网络.xml如下所示:

2022-09-02 10:57:39

我使用的是tomcat 6,球衣1.8,带有球衣guice和guice 3。我在设置中使用 JSP 时遇到问题。我有一个“状态”servlet,作为由web.xml配置的简单servlet,一个由GuiceFilter配置的球衣servlet,它返回一个jsp视图响应(jsp是/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被调用并得到一个带有“isJspServlet = true”和“jspFile = null”的标准Wrapper的请求调度程序。

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

顺便说一句,我已经在球衣邮件列表中阅读了2010年7月25日的帖子,但它对我不起作用。

帮助赞赏谢谢,艾莎

-- 附录 -- 我发现自己从业务逻辑代码调用 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 配置为“使用”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>

请注意,这是配置,而不是配置。filterservlet

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_404ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX

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

在下一步中,您还可以参考这个问题,具体涉及我将Guice AOP添加到此配置中以与Guice Dependency Injection,Jersey REST Services,Static Content(JavaScript,CSS,Images)和返回JSP Viewables一起工作的问题。


答案 2