使用JSF集成Flash文件上传 [英] Integrating Flash File Upload with JSF

查看:182
本文介绍了使用JSF集成Flash文件上传的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到,我们可以通过上传Flash文件上传多个文件。像 SWFUpload YUI上传器。是否有可能将这些上传组件与JSF?



我想要的是一次选择多个文件。 Primefaces文件上传器具有此功能,但在IE7中不起作用,因为IE7不支持HTML5。

我需要创建一个带有各种字段的表单,如下拉菜单,文本输入等,还需要添加一个文件上传器来选择多个文件。当JSF提交按钮将被点击时,表单将被验证,并且会在之后继续。



我已经创建了一个用于上传多个文件的页面,但是该页面使用多个输入文件组件为多个文件。



任何引用对我来说都是非常有帮助的。我发现了另一个 SO线程,并在那里发布了解决方案JSP。我不明白怎么才能用这个来满足我的要求。

$ h2更新

我已经创建了如下的managed bean:

  import com.mhis.massupload.ucm.Service; 

import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

import javax.faces.context.FacesContext;

import org.apache.commons.fileupload.FileItem;


public class UploadBean {
private Logger log = Logger.getLogger(getClass()。getName());
私人服务服务;
私有字符串键;

public UploadBean(){
super();
log.info(JYM);
init();

$ b $ private void init(){
key = UUID.randomUUID()。toString();


public String upload(){
System.out.println(Action Invoked。);
列表< FileItem> fileFields =(List< FileItem>)FacesContext.getCurrentInstance()。getExternalContext()。getSessionMap()。get(key);
System.out.println(fileFields);

return;
}

public void setKey(String key){
this.key = key;
}

public String getKey(){
return key;
}
}

而Servlet是:

  import java.io.IOException; 

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


公共类UploadServlet延伸的HttpServlet {

@SuppressWarnings( 兼容性:-3560436533054762606)
私有静态最后长的serialVersionUID = 4122845079663279030L;

public void init(ServletConfig config)throws ServletException {
super.init(config);

$ b $ public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
System.out.println(UploadServlet invoked。);
列表< FileItem> fileFields = new ArrayList< FileItem>();

尝试{
列表< FileItem> items = new ServletFileUpload(new DiskFileItemFactory())。parseRequest(request); (FileItem item:items){
if(!item.isFormField()){
fileFields.add(item);
System.out.println(item.getName());

$ b} catch(Exception e){
throw new ServletException(e);
}

String key = request.getParameter(key);
request.getSession()。setAttribute(key,fileFields);


$ / code $ / pre
$ b $ p jspx页面:

 <?xml version ='1.0'encoding ='utf-8'?> 
xmlns:f =http://java.sun。 com / jsf / core
xmlns:h =http://java.sun.com/jsf/html>
< jsp:output omit-xml-declaration =truedoctype-root-element =HTML
doctype-system =http://www.w3.org/TR/html4/ loose.dtd
doctype-public = - // W3C // DTD HTML 4.01 Transitional // EN/>
< jsp:directive.page contentType =text / html; utf-8/>
< f:view>
< html>
< head>
< meta http-equiv =Content-Typecontent =text / html; charset = utf-8/>
< script src =js / jquery-1.8.3.min.jstype =text / javascript>< / script>
< script src =uploadify / jquery.uploadify.jstype =text / javascript>< / script>
< link rel =stylesheetmedia =screenhref =uploadify / uploadify.css
type =text / css/>
< script type =text / javascript>
$(document).ready(function(){
$('#uploadify')。uploadify({
'swf':'uploadify / uploadify.swf',
'uploader':'$ {pageContext.request.contextPath} / uploadServlet; jsessionid = $ {pageContext.session.id}?key =< h:outputText value =#{uploadBean.key}/>'
});
});

var upload = function(){
$('#uploadify')。uploadify('upload','*');
}
< / script>
< title> test< / title>
< / head>
< body>
< h:form enctype =multipart / form-data>
< input id =uploadifytype =file/>
< / h:表格>
< / body>
< / html>
< / f:view>
< / jsp:root>

我在这里使用Uploadify。

我有两个问题:
$ b


  • 列表< FileItem> upload 方法的fileFields 有时会返回 null ,有时会显示列表。我无法找到原因。我试图通过 FacesContext.getCurrentInstance()从 action 方法获取 HttpSession 。 getExternalContext().getSession(false),然后调用 getAttribute(),也总是返回 null


  • 如果我设置了'auto':false,那么在调用上传之后, (); 方法并将< h:commandLink /> 修改为:< h:commandLink action = #{uploadBean.upload}value =Uploadonclick =upload();/> 然后我得到异常,即:

      org.apache.commons.fileupload.FileUploadBase $ IOFileUploadException:处理multipart / form-data请求失败。 2392369的:只有在阅读后EOF11626364承诺字节,其中有至少:0已经在org.apache.commons.fileupload.FileUploadBase.parseRequest缓冲
    (FileUploadBase.java:367 )美元,org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126 b $ b)
    在com.edfx.massupload.servlet.UploadServlet.doPost(UploadServlet.java:33)$在javax.servlet.http.HttpServlet.service在javax.servlet.http.HttpServlet.service b $ b(HttpServlet.java:727)
    (HttpServlet.java:820)
    。在weblogic.servlet。 internal.StubSecurityHelper $ ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute( ServletStubImpl.java:300)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)$ b在甲骨文$ b。 security.jps.ee.http.JpsAbsFilter 1.run $(JpsAbsFilter.java:119)
    在java.security.AccessController.doPrivileged(本机方法)$ B $在oracle.security.jps.util.JpsSubject湾doAsPrivileged(JpsSubject.java:315)
    at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:442)
    at oracle.security.jps.ee.http.JpsAbsFilter。 runJaasMode(JpsAbsFilter.java:103)
    at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:171)
    at oracle.security.jps.ee.http.JpsFilter。 doFilter(JpsFilter.java:71)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:139)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
    at weblogic.servlet .internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at weblogic.servlet.internal.Web AppServletContext $ ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)在weblogic.servlet.internal.WebAppServletContext
    $ ServletInvocationAction.run(WebAppServletContext.java:3681)
    at weblogic.security.acl.internal.AuthenticatedSubject。 DOAS(AuthenticatedSubject.java:321)
    在weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    在weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
    at weblogic.work .ExecuteThread.execute(ExecuteThread.java:209)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)




在这种情况下,在执行servlet之前, action 方法正在执行。



我该如何解决这两个问题?

PS



我需要修改uploadify.js来设置swf文件的正确路径,并更改取消按钮的css。我已经将uploadify的整个目录放在了Web内容中。

解决方案

您将需要一个servlet。我已经回答了一个Uploadify + Servlet问题,之前应该给出足够的线索: Uploadify插件不会调用Java Servlet 。 SWFUpload和YUI上传器的概念没有什么不同。请注意,您可以将简单的HTML放在JSF页面中,而不会出现任何问题。

您的主要问题是使JSF支持bean和HTTP servlet能够相互交换数据。为此,应该使用HTTP会话。首先让初始请求中的JSF bean生成一个唯一的键,用作会话属性名:

  key = UUID。 randomUUID()的toString(); 

然后,在您告诉Uploadify / SWFUpload / etc使用的上传网址中,您需要包含作为URL查询字符串参数的 jsessionid URL片段(以便servlet将使用相同的HTTP会话)和 (这样servlet将使用这个键来存储关于文件上传的相关状态)。假设您需要将其指定为JS对象键:

  url:'$ {pageContext.request.contextPath} / uploadServlet ; jsessionid = $ {pageContext.session.id}?key =< h:outputText value =#{uploadBean.key}/>'

现在,servlet将在同一个HTTP会话中调用(即 request.getSession()将完全相同如JSF中 ExternalContext#getSession()及其属性 getSessionMap()所示。所以,在 doPost()中就是这样:

  String key = request .getParameter( 钥匙); 
request.getSession()。setAttribute(key,someStateAboutTheUpload);

最后,当JSF即将处理表单提交时,只需按键你可以通过< input type =hidden> < t:saveState> $ b $ $ pre $ SomeState someState =(SomeState)externalContext.getSessionMap()。get(key) ;

这个唯一的键不是必需的,它甚至可以是一个静态键,每个视图的基础上生成的关键确保数据不会冲突当最终用户有相同的视图打开在同一会话中的多个浏览器选项卡/窗口。


I have seen that we can upload multiple files by flash file upload. Like SWFUpload or YUI Uploader. Is it possible to integrate these upload component with JSF?

What I want is to choose multiple file at once. Primefaces file uploader has this feature, but that don't work in IE7 as IE7 don't have any support for HTML5.

I need to create a Form with various fields, like dropdown menu, text input etc and also need to add a file uploader for choosing multiple file. When the JSF submit button will be clicked the Form will be validated and it will proceed after.

I have created a page for uploading multiple file, but that page use multiple input file component for multiple file.

Any reference would be very helpful for me. I have found another SO thread and the solution posted there use JSP. I cannot understand how can I use this to fulfill my requirement.

Update

I have created the following managed bean:

import com.mhis.massupload.ucm.Service;

import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

import javax.faces.context.FacesContext;

import org.apache.commons.fileupload.FileItem;


public class UploadBean { 
    private Logger log = Logger.getLogger(getClass().getName());
    private Service service;
    private String key;

    public UploadBean() {
        super();
        log.info("JYM");
        init();
    }

    private void init() {
        key = UUID.randomUUID().toString();
    }

    public String upload() {        
        System.out.println("Action Invoked.");
        List<FileItem> fileFields = (List<FileItem>)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);
        System.out.println(fileFields);

        return "";
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getKey() {
        return key;
    }
}

And the Servlet is:

import java.io.IOException;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class UploadServlet extends HttpServlet {

    @SuppressWarnings("compatibility:-3560436533054762606")
    private static final long serialVersionUID = 4122845079663279030L;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("UploadServlet invoked.");        
        List<FileItem> fileFields = new ArrayList<FileItem>();

        try {
            List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
            for (FileItem item : items) {
                if (!item.isFormField()) {
                    fileFields.add(item);
                    System.out.println(item.getName());
                }
            }
        } catch (Exception e) {
            throw new ServletException(e);
        }

        String key = request.getParameter("key");
        request.getSession().setAttribute(key, fileFields);
    }
}

The jspx page:

<?xml version='1.0' encoding='utf-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html">
  <jsp:output omit-xml-declaration="true" doctype-root-element="HTML"
              doctype-system="http://www.w3.org/TR/html4/loose.dtd"
              doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
  <jsp:directive.page contentType="text/html;utf-8"/>
  <f:view>
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <script src="js/jquery-1.8.3.min.js" type="text/javascript"></script>        
        <script src="uploadify/jquery.uploadify.js" type="text/javascript"></script>
        <link rel="stylesheet" media="screen" href="uploadify/uploadify.css"
              type="text/css"/>
        <script type="text/javascript">
            $(document).ready(function() {
                $('#uploadify').uploadify({
                    'swf': 'uploadify/uploadify.swf',
                    'uploader': '${pageContext.request.contextPath}/uploadServlet;jsessionid=${pageContext.session.id}?key=<h:outputText value="#{uploadBean.key}" />'                   
                });                                         
            });    

            var upload = function() {
                $('#uploadify').uploadify('upload','*');
            }
        </script>
        <title>test</title>
      </head>
      <body>
        <h:form enctype="multipart/form-data">
            <input id="uploadify" type="file"/>            
            <h:commandLink action="#{uploadBean.upload}" value="Upload" />
        </h:form>
      </body>
    </html>
  </f:view>
</jsp:root>

I am using Uploadify here.

I am having two issues:

  • The List<FileItem> fileFields of the upload method is sometime returning null, sometime showing the list. I am unable to find the reason. I have tried to get the HttpSession from the action method by FacesContext.getCurrentInstance().getExternalContext().getSession(false) and then called getAttribute() upon it, that is also always returning null.

  • If I set 'auto': false, that is the file upload will launch after calling upload(); method and modify the <h:commandLink/> as: <h:commandLink action="#{uploadBean.upload}" value="Upload" onclick="upload();"/> then I am getting exception, which is:

    org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. EOF after reading only: '2392369' of: '11626364' promised bytes, out of which at least: '0' were already buffered
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:367)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
    at com.edfx.massupload.servlet.UploadServlet.doPost(UploadServlet.java:33)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:119)
    at java.security.AccessController.doPrivileged(Native Method)
    at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
    at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:442)
    at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:103)
    at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:171)
    at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:139)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
    

And also in this case the action method is executing before the servlet get executed.

How can I solve these two issues?

PS

I need to modify the uploadify.js to set the correct path of the swf file and changed the css for the cancel-button. I have placed the whole directory of the uploadify inside Web-Content.

解决方案

You're going to need a servlet for this. I've answered a Uploadify + Servlet question before which should give sufficient clues: Uploadify plugin doesn't call Java Servlet. The concept is not that different for SWFUpload and YUI Uploader. Note that you can just put plain HTML in a JSF page without problems.

Your main problem is enabling the JSF backing bean and the HTTP servlet to exchange data with each other. For this the HTTP session should be used. First let the JSF bean on initial request generate an unique key which is to be used as session attribute name:

key = UUID.randomUUID().toString();

Then, in the upload URL which you tell Uploadify/SWFUpload/etc to use, you need to include the jsessionid URL fragment (so that the servlet will use the same HTTP session) and the keyas URL query string parameter (so that the servlet will use this key to store relevant state about the file upload). Assuming that you need to specify it as a JS object key:

url: '${pageContext.request.contextPath}/uploadServlet;jsessionid=${pageContext.session.id}?key=<h:outputText value="#{uploadBean.key}" />'

Now, the servlet will be invoked within the same HTTP session (i.e. request.getSession() will be exactly the same one as available in JSF by ExternalContext#getSession() and its attributes by getSessionMap()). So, in doPost() just do:

String key = request.getParameter("key");
request.getSession().setAttribute(key, someStateAboutTheUpload);

Finally, when JSF is about to process the form submit, just get the desired data by the key (which you store for the subsequent request by <input type="hidden"> or <t:saveState> in case of a request scoped bean):

SomeState someState = (SomeState) externalContext.getSessionMap().get(key);

The unique key is not necessary for the functioning, it can even be a static key, but a on per-view basis generated key ensures that the data doesn't clash when the enduser has the same view open in multiple browser tabs/windows in the same session.

这篇关于使用JSF集成Flash文件上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆