在基于WebSphere JSF 1.2 Portlet Bridge的JSF Portlet中实现文件下载
来源:互联网 发布:java发送qq消息接口 编辑:程序博客网 时间:2024/05/16 23:01
本文讨论在基于WebSphere JSF 1.2 Portlet Bridge的JSF Portlet中实现文件下载。
JSR 286规范提供了一个基于resource serving的文件下载机制,但由于JSF 1.2 Portlet Bridge并没有提供相应的支持,所以必须在混合使用portlet和JSF来实现这个机制。
具体的实现包含三部分: 一个继承FacesPortlet并实现serveResource方法的portlet类, 一个显示下载链接的JSF页面, 以及一个提供文件内容的JSF managed bean。
portlet类
package demo;import java.io.IOException;import java.io.OutputStream;import javax.el.ExpressionFactory;import javax.el.ValueExpression;import javax.faces.context.FacesContext;import javax.faces.lifecycle.Lifecycle;import javax.portlet.PortletException;import javax.portlet.PortletSession;import javax.portlet.ResourceRequest;import javax.portlet.ResourceResponse;import com.ibm.faces.portlet.FacesPortlet;import com.ibm.faces.portlet.httpbridge.PortletRequestWrapper;import com.ibm.faces.portlet.httpbridge.PortletResponseWrapper;import com.ibm.faces.portlet.httpbridge.ResourceRequestWrapper;import com.ibm.faces.portlet.httpbridge.ResourceResponseWrapper;public class JSFPortlet extends FacesPortlet {@Overridepublic void serveResource(ResourceRequest request, ResourceResponse response)throws PortletException, IOException {super.serveResource(request, response);TestBean testBean = (TestBean) getJSFManagedBean(request, response, TestBean.BEAN_NAME, TestBean.class);final OutputStream out = response.getPortletOutputStream();byte[] bytes = testBean.getCsv();response.setContentType("text/csv");response.setProperty("Content-Disposition","attachment; filename=download.csv");response.setProperty("Content-length", String.valueOf(bytes.length));out.write(bytes);out.flush();out.close();}public Object getJSFManagedBean(ResourceRequest request,ResourceResponse response, String beanName, Class beanClass)throws PortletException {PortletSession portletSession = request.getPortletSession();Object jsfBean = (TestBean) portletSession.getAttribute(beanName);if (jsfBean == null) {PortletRequestWrapper requestWrapper = new ResourceRequestWrapper(request);requestWrapper.setPortletContext(getPortletContext());PortletResponseWrapper responseWrapper = new ResourceResponseWrapper(response);Lifecycle lifecycle = getLifecycle(requestWrapper);FacesContext context = getFacesContext(requestWrapper,responseWrapper, lifecycle);final ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory();final ValueExpression valueExpression = expressionFactory.createValueExpression(context.getELContext(), "#{" + beanName + "}", beanClass);jsfBean = (TestBean) valueExpression.getValue(context.getELContext());}return jsfBean;}}
JSF页面
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%><%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%><%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%> <%@taglib uri="http://www.ibm.com/xmlns/prod/websphere/portal/v6.1/portlet-client-model" prefix="portlet-client-model" %> <%@ page language="java" contentType="text/html" pageEncoding="ISO-8859-1" session="false"%><portlet:defineObjects /><portlet-client-model:init> <portlet-client-model:require module="ibm.portal.xml.*"/> <portlet-client-model:require module="ibm.portal.portlet.*"/> </portlet-client-model:init> <f:view> <portlet:resourceURL var="resourceUrl" > <portlet:param name="action" value="csv" /> </portlet:resourceURL> <a href="<%=resourceUrl%>">Download CSV</a> </f:view>
JSF managed bean
package demo;import java.util.Date;public class TestBean {public static final String BEAN_NAME = "testBean";public byte[] getCsv() { return new Date().toString().getBytes(); }public String getText() {return "Hello";}}
开发中的一些发现:
- IBM JSF 1.2 Portlet Bridge没有提供portlet tag的对应Facelet taglib xml, 因此不能在基于Facelet的JSF页面中使用<portlet:resourceURL>。 这个问题已经在IBM JSF 2 Portlet Bridge中得到解决。
- <portlet:resourceURL> tag提供一个var属性, 可以用来定义一个变量来保存resource URL供页面上得其他代码使用。 JSR 286规范将该变量定义于JSP page scope中。 由于JSF无法访问JSP page scope, 因此页面上的JSF组件也无法使用该变量。
- 在传统的Servlet编程中,我们使用response.setHeader方法来设置HTTP response的头信息,包括Content-Disposition和Content-length, 而在portlet中,我们使用ResourceResponse.setProperty方法。
-在portlet中可以通过两种方法来访问JSF managed beans, 如果要访问的JSF managed bean是一个session scope bean 且已存在于session只用, 那么可以使用portletSession.getAttribute(BEAN_NAME)来获取该bean, 否则的话, 就必须从FacesContext中使用JSF value expression表达式来创建和获取该bean。 由于IBM JSF 1.2 Portlet Bridge并没有提供一个直接的方法来获取FacesContext, 必须使用一些内部代码来实现该功能。
- 在基于WebSphere JSF 1.2 Portlet Bridge的JSF Portlet中实现文件下载
- jboss portal (基于jsp的portlet,JSF)
- IBM WebSphere Portal 7下开发支持AJAX的JSF Portlet
- jsf 实现文件下载
- 使用 Rational Application Developer 6.0 和 WebSphere Portal Server 5.1开发 JSF portlet
- 【JSF小记】JSF实现简单的文件下载
- 在基于XMLAccess的Portlet发布中使用WAR文件名
- JSF文件下载的不同实现
- 基于Struts2构建 WebSphere Portal上的Portlet应用
- 用JSF实现文件下载
- 在web Portal中实现可脱拽Portlet的方法
- 在web Portal中实现可脱拽Portlet的方法
- 在web Portal中实现可脱拽Portlet的方法
- 在web Portal中实现可脱拽Portlet的方法
- 在web Portal中实现可脱拽Portlet的方法
- 在web Portal中实现可脱拽Portlet的方法
- 在web Portal中实现可脱拽Portlet的方法
- 在web Portal中实现可脱拽Portlet的方法
- 目前做互联网最重要的就是定位和执行力
- per cpu 变量
- BS与CS的差别
- 黑马程序员_Java包和多线程
- Android 杀掉自己进程的方法
- 在基于WebSphere JSF 1.2 Portlet Bridge的JSF Portlet中实现文件下载
- Grape
- LINQ表达式总结笔记
- 用ECLiPSe解决爱因斯坦养鱼问题
- 黑马程序员_基础学习笔记(5)
- 通过中值滤波,归一化对比LAMOST与SDSS的光谱
- Android Service 详解五:前台运行与生命期
- git命令
- Tomcat下Servlet的开发