使用JSF 1.2添加一个输入文件



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

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

自从我不得不为JSF编写MIME解析器以来已经有一段时间了,但这是我对这个过程的记忆。

您需要编写一个解析器来从multi-part/formdata有效负载中提取数据。在W3站点上有关于multi-part/formdata的一个很好的概述。

你需要决定是否瞄准:

  • 一个非jsf servlet,带有一个普通的表单/控件
  • 带有JSF表单和自定义文件上传控件的JSF servlet

针对普通servlet

只要上传POST操作不需要调用依赖于JSF上下文(托管bean等)的代码,这将是一种更简单的方法

您的servlet解析来自输入流的数据并适当地对其进行操作。

瞄准JSF视图/动作

在这里,您需要修饰请求(理想情况下使用HttpServletRequestWrapper),以便向JSF框架提供解析后的参数。这通常是在一个过滤器中完成的,该过滤器从HTTP报头中检测帖子类型。在调用任何表单操作之前,需要决定文件数据存储在哪里,以及如何将该数据公开给托管bean。

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

检查不能使用的解析器/控件的特性是值得的,以确保您提供了简单的特性-例如最大有效负载大小,以防止攻击者向您的应用程序上传千兆字节的数据。

为了用一个可接受的解决方案解决这个问题,我创建了一个普通表单和一个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;

}

我以前也遇到过同样的问题。我通过在用户点击浏览按钮时打开一个弹出窗口来解决这个问题,这个新的弹出窗口直接链接到一个支持文件上传和下载的servlet。一旦文件被上传,弹出窗口就会被servlet在加载servlet主体时调用window.close()直接关闭。修改如下:

在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:UsersKISHOREDesktopeclipse
                    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.pluginsorg.eclipse.wst.server.coretmp0wtpwebappsShoppingCartWEB-INFitemImagesEC34EEE58065AD674192D3D57124F07E.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上找到了其他方法,但感觉实现起来有点复杂。

相关内容

  • 没有找到相关文章

最新更新