如何在JSP页面中包含JSP页面?
我在Facelets上使用Myfaces 2。 我必须在Facelet页面中包含一个JSP页面。 我试过使用<ui:include>
,但它只需要XHTML页面。 我也试过使用<c:import>
和<f:subview>
,但没有任何工作。 谷歌搜索了很多,但没有得到确切的答案。如何在JSP页面中包含JSP页面?
我该如何达到要求?
你不行。 JSP和facelets不能一起评估 - 你只有一个视图处理器,它处理facelets而不是JSP。
<c:import>
会工作,如果可以通过HTTP访问jsp,因此它的输出将被包括在内,而不是代码。
这是可能的自定义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应用程序。
这种方法似乎不适合我,http:// stackoverflow。com/questions/10128023/unable-to-add-jsp-page-to-xhtml-page – Rachel 2012-04-12 16:49:47
我确认这也适用于xhtml页面。做这样的事情有什么缺点吗?像一些请求映射变量被创建的不同FacesContexts使用... – Nerrve 2012-05-30 12:42:15
@Nerrve:它共享相同的HTTP请求,所以JSP/Servlet有机会访问和操纵所有请求/会话/应用程序属性JSF使用。顺便说一句,这是因为它很快也可以作为OmniFaces中的可重用组件(具有改进的'HttpServletResponseWrapper',可以将字符编码考虑在内)。另请参阅https://showcase-omnifaces.rhcloud.com/showcase/components/resourceInclude.xhtml – BalusC 2012-05-30 12:59:30
你采取了iframe吗? – Ankit 2011-05-24 07:02:26