2

ファイルのアップロード専用のフォームでアップロードする必要があります。私のプロジェクトでは、JSF 1.2 と RichFaces 3.3.3 を使用でき<rich:fileUpload/>ますが、クライアントが のような単純な入力を必要とするため、を使用できません<input type="file"/>

可能であれば、Primeface または Tomahawk のファイル アップロードを使用したいのですが、禁止されています。他のライブラリは使用できません。Servlet 3.0 や Apache ファイル アップロードも使用できません。今何ができますか?私は他の同様の質問を見てきましたが、彼らは他のライブラリを使用することができました.私はできません.私は制限されています...

4

3 に答える 3

2

JSF 用の MIME パーサーを作成する必要が生じてからしばらく経ちましたが、このプロセスについて覚えていることは次のとおりです。

multi-part/formdataペイロードからデータを抽出するには、パーサーを作成する必要があります。W3 サイトにの優れた概要multi-part/formdataがあります。

以下をターゲットにするかどうかを決定する必要があります。

  • プレーンなフォーム/コントロールを持つ非 JSF サーブレット
  • JSF フォームとカスタム ファイル アップロード コントロールを備えた JSF サーブレット

プレーンなサーブレットをターゲットにする

これは、アップロード POST アクションが JSF コンテキスト内にあることに依存するコード (マネージド Bean など) を呼び出す必要がない限り、より単純なアプローチになります。

サーブレットは、入力ストリームからのデータを解析し、適切に処理します。

JSF ビュー/アクションのターゲット設定

HttpServletRequestWrapperここでは、解析されたパラメーターを JSF フレームワークに提供するために、要求を (理想的には で) 装飾する必要があります。これは通常、HTTP ヘッダーから投稿タイプを検出するフィルターで行われます。フォーム アクションを呼び出す前に、ファイル データを格納する場所と、そのデータをマネージド Bean に公開する方法を決定する必要があります。

また、ファイル アップロードの入力タイプ用のカスタム JSF コントロールを作成するかどうか、またはプレーンな HTML 要素を使用できるかどうかも考慮する必要があります。

使用できないパーサー/コントロールの機能を調べて、攻撃者がギガバイトのデータをアプリケーションにアップロードするのを防ぐための最大ペイロード サイズなどの単純な機能を提供することを確認することは価値があります。

于 2013-01-10T09:49:30.120 に答える
1

この問題を許容可能な解決策で解決するために、通常のフォームとサーブレットを作成しました。サーブレットはmultipart/form-dataリクエストを受信しorg.ajax4jsf.request.MultipartRequest、RichFaces 3.3.3 に含まれている を使用して、受信したパラメーターと添付ファイルを解析し、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>

サーブレット:

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;


}
于 2013-01-10T18:50:30.713 に答える
0

私は以前に同じ問題に直面していました。ユーザーが参照ボタンをクリックしたときにポップアップを開くことで問題を解決しました。この新しいポップアップは、ファイルのアップロードとダウンロードをサポートするサーブレットに直接リンクされていました。ファイルがアップロードされると、ポップアップはサーブレット本体のロード時に 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>

これはサーブレットに送信され、サーブレットは画像をレンダリングして特定の場所に保存します。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>");
    }

このサーブレットは、構成された場所でのファイルの保存が完了すると、以前に開いていたポップアップを直接閉じます。

このようにして、管理対象の Bean である jsf 1.2 を使用して、フィールドのアップロードを実現できました。stackoverflow で他の方法を見つけましたが、実装が少し複雑だと感じました。

于 2013-04-01T09:00:22.747 に答える