2011-05-24 140 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