【问题标题】:Jersey Guice JSP how to?Jersey Guice JSP如何?
【发布时间】:2011-11-04 03:50:55
【问题描述】:

我正在使用带有 jersey guice 和 guice 3 的 tomcat 6、jersey 1.8。 我在设置中使用 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;

这一切都与简单的 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 并没有什么好处。

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

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

【问题讨论】:

  • 嘿伙计,这个问题好运吗?我似乎得到了同样的东西
  • 不,我发现自己从代码中调用 JSP,丑陋但有效。将添加为“答案”
  • 我最终放弃了 JSP 并选择了 Freemarker。
  • 您是否尝试设置JSP模板路径? IE。 com.sun.jersey.config.property.JSPTemplatesBasePath /WEB-INF/jsp

标签: java jsp jersey guice


【解决方案1】:

问题是由于将 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 依赖注入、Jersey REST 服务、静态内容(JavaScript、CSS、图像)并返回 JSP 一起工作时遇到的问题可见。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 2013-08-07
    • 2013-05-21
    • 2013-06-21
    • 2012-08-12
    相关资源
    最近更新 更多