2011-05-24 141 views
4

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

我该如何达到要求?

+0

你采取了iframe吗? – Ankit 2011-05-24 07:02:26

回答

1

你不行。 JSP和facelets不能一起评估 - 你只有一个视图处理器,它处理facelets而不是JSP。

<c:import>会工作,如果可以通过HTTP访问jsp,因此它的输出将被包括在内,而不是代码。

4

这是可能的自定义UIComponent。我的同事在一年前写了一篇博客文章:Facelets and legacy JSP

这是一些代码,但原理很简单,该组件执行一个RequestDispatcher#include()自定义HttpServletResponseWrapper捕获写入的输出,然后将其写入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迁移与臭脚本和所有他们到一个更加理智和现代的Facelets应用程序。

+0

这种方法似乎不适合我,http:// stackoverflow。com/questions/10128023/unable-to-add-jsp-page-to-xhtml-page – Rachel 2012-04-12 16:49:47

+0

我确认这也适用于xhtml页面。做这样的事情有什么缺点吗?像一些请求映射变量被创建的不同FacesContexts使用... – Nerrve 2012-05-30 12:42:15

+0

@Nerrve:它共享相同的HTTP请求,所以JSP/Servlet有机会访问和操纵所有请求/会话/应用程序属性JSF使用。顺便说一句,这是因为它很快也可以作为OmniFaces中的可重用组件(具有改进的'HttpServletResponseWrapper',可以将字符编码考虑在内)。另请参阅https://showcase-omnifaces.rhcloud.com/showcase/components/resourceInclude.xhtml – BalusC 2012-05-30 12:59:30