如何在 Facelet 页面中包含 JSP 页面



我在Facelets上使用Myfaces 2。我必须在 Facelet 页面中包含 JSP 页面。我尝试使用<ui:include>但它只需要XHTML页面。我也尝试使用<c:import><f:subview>但没有任何效果。谷歌搜索了很多,但没有得到确切的答案。

如何满足要求?

这可以通过自定义UIComponent来实现。我的同事一年前写了一篇关于这个问题的博客文章:Facelets和遗留JSP。

这是一些代码,但原理很简单,组件使用自定义HttpServletResponseWrapper执行RequestDispatcher#include(),该捕获写入的输出,然后将其写入 JSF 组件的主体。以下是相关的摘录:

创建类com.example.component.JspIncludeComponent

public class JSPIncludeComponent extends UIComponentBase {
    public String getFamily() {
       return "components.jsp.include";
    }
    public void encodeBegin(FacesContext context) throws IOException {
       try {
          ExternalContext externalContext = context.getExternalContext();
          HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
          HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
          // Create dispatcher for the resource given by the componen's page attribute.
          RequestDispatcher requestDispatcher = request.getRequestDispatcher((String) getAttributes().get("page"));
          // Catch the resource's output.
          CharResponseWrapper responseWrapper = new CharResponseWrapper(response);
          requestDispatcher.include(request, responseWrapper);
          // Write the output from the resource to the JSF response writer.
          context.getResponseWriter().write(responseWrapper.toString());
       }
       catch (ServletException e) {
          throw new IOException();
       }
    }
}

创建类com.example.CharResponseWrapper

public class CharResponseWrapper extends HttpServletResponseWrapper {
   private CharArrayWriter output;
   @Override
   public String toString() {
      return output.toString();
   }
   public CharResponseWrapper(HttpServletResponse response) {
      super(response);
      output = new CharArrayWriter();
   }
   public CharArrayWriter getCharWriter() {
      return output;
   }
   @Override
   public PrintWriter getWriter() {
       return new PrintWriter(output);
  }
   @Override
   public ServletOutputStream getOutputStream() {
      return new CharOutputStream(output);
   }
   public InputStream getInputStream() {
      return new ByteArrayInputStream( toString().getBytes() );
   }
}
class CharOutputStream extends ServletOutputStream {
   private Writer output;
   public CharOutputStream( Writer writer ) {
      output = writer;
   }
   @Override
   public void write(int b) throws IOException {
      output.write(b);
   }
}

添加faces-config.xml

<component>
    <component-type>com.example.component.JSPIncludeComponent</component-type>
    <component-class>com.example.component.JSPIncludeComponent</component-class>
</component>

在 WEB-INF 文件夹中创建文件my.taglib.xml (Facelet taglib(

<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://example.com/jsf</namespace> 
    <tag>
      <tag-name>include</tag-name>
      <component>
        <component-type>com.example.component.JSPIncludeComponent</component-type>
      </component>
    </tag>
</facelet-taglib>

添加到web.xml(如 http://docs.oracle.com/javaee/6/tutorial/doc/bnawn.html 中所述(

<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>

这样您就可以将其用作

<ui:component 
    xmlns:my="http://example.com/jsf"
    xmlns:ui="http://java.sun.com/jsf/facelets"
>
    <my:include page="page.jsp" />
</ui:composition>

最后但并非最不重要的一点是,记住他的遗言

我不建议将其用作持久的解决方案,但它可能会简化从带有臭脚本的传统 JSP 的迁移,并且所有这些都在它们上迁移到更理智和现代的 Facelet 应用程序。

你不能。JSP 和 facelet 不能一起评估 - 你只有一个视图处理程序,它处理的是 facelet,而不是 JSP。

如果 JSP 可以通过 http 访问,<c:import> 就可以工作,因此将包含其输出,而不是代码。

相关内容

  • 没有找到相关文章

最新更新