2013-01-09 61 views
1

我需要上传专用于上传文件的表单。在我的项目中,我可以使用JSF 1.2和RichFaces 3.3.3,但我不能使用<rich:fileUpload/>,因为我的客户想要一个简单的输入,就像<input type="file"/>使用JSF 1.2添加输入文件

如果我可以使用Primeface或Tomahawk的文件上传,但是我被禁止,我不能使用其他库,我也不能使用Servlet 3.0 nether Apache fileupload。我现在能做什么?我见过其他类似的问题,但他们可以使用其他库,我只是不能,我受限制...

+0

为什么选择投票?评论,而不是倒票和走开¬¬ –

+0

这将是最简单的使用第三方控制或图书馆。由于这不是一个选项,你将不得不开始阅读MIME规范,因为你将要编写一个MIME解析器。 – McDowell

+0

@McDowell是的,我知道这将是waaay更简单,我也做了一个使用lib的版本,它被拒绝:/我目前正在尝试使用servlet来接收文件... –

回答

1

要使用我创建了一个正常形式和一个servlet可接受的解决方案解决这个问题,servlet接收的multipart/form-data请求和使用包括在RichFaces的3.3.3来解析所接收的参数和附加的文件中org.ajax4jsf.request.MultipartRequest,那么我在会话中保存File实例,并在JSF上下文中恢复它。

XHTML:

<a4j:form > 
    <a4j:jsFunction name="finishUpload" 
      action="#{importacaoController.actionUploadArquivoDadosXX}" 
      reRender="uploadedFile,globalMensagens" /> 
    <a4j:jsFunction 
     name="tipoNaoSuportado" reRender="globalMensagens" action="#{importacaoController.actionTipoNaoSuportado }" 
     /> 
</a4j:form> 
<form target="uploader" id="uploaderForm" action="#{request.contextPath}/MyServlet" 
    method="post" enctype="multipart/form-data" style="position: absolute;margin: -210px 0 0 300px;"> 
    <div class="modulo-6-12"> 
     <label for="uploadFileField">Anexar arquivo</label><br/> 
     <input type="file" id="uploadFileField" name="upload" onchange="jQuery('#uploaderForm').submit();" /> 
    <br /> 
    <small><h:outputText id="uploadedFile" value="#{importacaoController.arquivoConfig.name}" /></small> 
    </div> 
</form> 
<iframe id="uploader" width="0" height="0" src="" style="display: none; border: 0; margin:0;padding:0;"></iframe> 

的Servlet:

public class MyServlet extends HttpServlet { 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     String encoding = request.getCharacterEncoding(); 
     if(encoding == null) request.setCharacterEncoding("UTF-8"); 
     MultipartRequest mpRequest = new MultipartRequest(request,true,10*1024*1024,"importarXX"); 
     String field = "upload"; 
     Object o =mpRequest.getFile(field); 
     if(o instanceof File) 
     { 
      File file = (File)o; 
      HttpSession sess = request.getSession(); 
      String name = mpRequest.getFileName(field); 

      Writer w = response.getWriter(); 
      w.write("<html><head><script>"); 
      if(!name.endsWith(".xls")) 
      { 

       w.write("parent.window.tipoNaoSuportado()" + 
         //"alert('Só são permitidos arquivos com extensão .xls');" + 
         "</script></head><body></body></html>"); 
       w.close(); 
       file.delete(); 
       return; 
      } 

      sess.setAttribute("importarXXFile", o); 
      sess.setAttribute("importarXXFileName", name); 
      w.write("parent.window.finishUpload();</script></head><body>Sucesso</body></html>"); 
      w.close(); 
     } 
    } 
} 

控制器:

public boolean actionUploadArquivoDadosXX(){ 
    flgTipoNaoSuportado = false; 
    HttpSession sess = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession(); 
    File uploadedFile = (File) sess.getAttribute("importarXXFile"); 
    String uploadedFileName = (String) sess.getAttribute("importarXXFileName"); 
    boolean ret = false; 

    if(uploadedFile != null && uploadedFileName != null){ 
     BeanArquivoUpload arquivo = new BeanArquivoUpload(); 
     arquivo.setFile(uploadedFile); 
     arquivo.setName(uploadedFileName); 
     arquivo.setFileSize(uploadedFile.length()); 
     setArquivoConfig(arquivo); 
     ret = true; 
    } 
    else 
    { 
     setArquivoConfig(null); 
    } 

    sess.removeAttribute("importarXXFile"); 
    sess.removeAttribute("importarXXFileName"); 

    return ret; 


} 
1

已经有一段时间了,因为我不得不为JSF编写MIME解析器,但是这个我记得这个过程。

您需要编写一个解析器来从multi-part/formdata负载中提取数据。有一个很好的overview of multi-part/formdata on the W3 site

你需要决定是否目标:

  • 非JSF的servlet用普通的形式/控制
  • 一个JSF的servlet与JSF窗体和一个自定义文件上传控制

瞄准一个普通的servlet

这将是更简单的方法,只要上传POST操作没有按” t需要调用依赖于JSF上下文中的代码(托管bean等)

您的servlet解析来自输入流的数据,并根据需要对其执行操作。

瞄准一个JSF视图/动作

在这里,你将需要装饰的要求(最好是使用HttpServletRequestWrapper)提供解析parameters JSF框架。这通常会在filter中完成,它会从HTTP头中检测帖子类型。在调用任何表单操作之前需要决定文件数据的存储位置,以及如何将这些数据公开到托管bean。

您还需要考虑是否要为文件上传输入类型创建自定义JSF控件,或者是否可以使用纯HTML元素逃脱。

这是值得研究的解析器/控件的功能,你不能用它来确保你提供简单的功能 - 如最大有效载荷大小,以防止攻击者上传千兆字节的数据到你的应用程序。

+0

谢谢,但经过数小时的努力许多方法来做上传我发现n由RichFaces('org.ajax4jsf.request.MultipartRequest')中包含的Ajax4J的多部分实现,所以我不需要自己实现它:) –

0

我以前遇到过同样的问题。我通过在用户点击浏览按钮时打开弹出窗口来解决问题,并且此新弹出窗口直接链接到支持文件上载和下载的servlet。 上传文件后,弹出窗口直接由servlet调用window.close()加载servlet主体来关闭。 如下的变化来完成:

在addItem.jsp它会提示用户输入一个文件:

<script type="text/javascript"> 
     ... 
    function newWindow() 
    { 
    popupWindow = window.open('addItemImage.jsp','name','width=200,height=200'); 
    } 
    ... 
</script> 

    <f:view> 
     <h:form id="search" onsubmit="return validateDetails()"> 
      ... 

      <h:panelGroup> 
       <font color="black">Item Image :</font> 
      </h:panelGroup> 
      <h:panelGroup> 
       <input type="button" value="Upload Image" onClick="newWindow()"/> 
      </h:panelGroup> 

      ... 
      </h:form> 
     </f:view> 

在新弹出的窗口已打开:addItemImage.jsp

<script type="text/javascript"> 
    function validate() 
    { 
     var file = document.getElementById("file").value; 
     if(file == null || file == "") 
      return true; 
     if(file.indexOf(".jpg") == -1 && file.indexOf(".gif") && file.indexOf(".bmp") == -1 && file.indexOf(".jpeg") == -1) 
     { 
      alert("Invalid File Format!! Please upload jpg/bmp/gif"); 
      return false; 
     } 
     return true; 
    } 
</script> 
<body> 
    <form enctype="multipart/form-data" method="post" action="FileUploaderServler.view" onsubmit="return validate()"> 
     <input type="file" name="file" id="file" /> 
     <input type="submit" value="Upload Image"> 
    </form> 
</body> 

这将张贴到一个servlet,然后将呈现图像并将其保存在一个地方。 FileUploaderServlet.java

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    { 
     List<FileItem> items = null; 
     try 
     { 
      MultipartHTTPServletRequest multipartHTTPServletRequest = new MultipartHTTPServletRequest(Connection.getRequest()); 
      items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(multipartHTTPServletRequest); 
     } 
     catch (FileUploadException e) 
     { 
      e.printStackTrace(); 
     } 
     if(!Util.isNullList(items)) 
     { 
      for (FileItem item : items) 
      { 
       if (!item.isFormField()) 
       { 
        String itemName = item.getFieldName(); 
        InputStream filecontent = null; 

        try 
        { 
         filecontent = item.getInputStream(); 
        } 
        catch (IOException e) 
        { 
         e.printStackTrace(); 
        } 

        /* String currDirPath = System.getProperty("user.dir"); // C:\Users\KISHORE\Desktop\eclipse 
        File file = new File(currDirPath+"\\itemImages");*/ 
        new File(Constants.ABS_FILE_PATH_TO_IMAGES).mkdir(); 
        File fw = new File(Constants.ABS_FILE_PATH_TO_IMAGES+"\\"+Connection.getRequest().getSession().getId()+".jpg"); // E:\Kishore Shopping Cart\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ShoppingCart\WEB-INF\itemImages\EC34EEE58065AD674192D3D57124F07E.jpg 
        fw.delete(); 
        fw.createNewFile(); 
        try 
        { 
         item.write(fw); 
        } 
        catch (Exception e) 
        { 
         e.printStackTrace(); 
        } 
       } 
      } 

     } 

     PrintWriter out = response.getWriter(); 
     out.print("<html><title>Add Image to Item</title><body onload='window.close()'>Uploaded Successfully!!</body>"); 
     System.out.print("</html>"); 
    } 

这个servlet在上配置的地方,保存文件将直接关闭先前打开弹出的完成。

所以这样我就可以使用托管bean jsf 1.2并实现上传。 我在stackoverflow上找到了其他方法,但是觉得实现起来有点复杂。