連載
» 2004年12月14日 10時00分 UPDATE

JavaTips 〜Apache/Jakarta編:ファイルアップロード処理を簡単にする(Commons活用)

[山田祥寛,@IT]

 従来、JSP/サーブレットにおいて、アップロード処理を実現するのは困難でした。というのも、JSP&サーブレットAPI、あるいはJavaコアAPIが標準で備えるライブラリには、アップロード処理に特化したライブラリが存在しなかったためです。そのため、アップロード機能をアプリケーションに組み込むには、POSTされた生のリクエストデータを解析し、ファイル名やその本体データを取り出すという処理を自分自身で行わなければならなかったのです。本稿では、その泥臭い作業手順については触れませんが、これが大変面倒なものであろうことは想像に難くないでしょう。

 しかし、Jakarta Commonsサブプロジェクトから公開されているFileUploadライブラリを利用することで、従来の煩雑なアップロード処理の大半は軽減されます。論より証拠、早速具体的なサンプルコードを見てみることにしましょう。

解説

 サンプルコードは、アップロードファイルをエントリするJSPページと、実際のアップロード処理を行うサーブレットクラスから構成されます。また、サーブレットクラスの動作にはデプロイメント・ディスクリプタ(web.xml)への登録が必須です。web.xmlへの設定については、連載:基礎から学ぶサーブレット/JSP(11)「JSPとサーブレットの違いを明らかにする」を参照してください。

upload.jsp
<%@ page contentType="text/html;charset=Windows-31J" %>
<html>
<head>
<title>ファイルのアップロード</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data" 
        action="UploadServlet">
ファイルパス:
<input type="file" name="fl" size="75" />
<input type="submit" value="アップロード" />
</form>
</body>
</html>


UploadServlet.java
package to.msn.wings.javatips;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

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

import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;

public class UploadServlet extends HttpServlet {
  public void doPost(HttpServletRequest request
                    , HttpServletResponse response)
  throws ServletException, IOException {
    String path=getServletContext().getRealPath("WEB-INF/data");
    DiskFileUpload objDfu=new DiskFileUpload();
    // アップロードファイルの最大サイズ(-1は無限)
    objDfu.setSizeMax(-1);  
    // バッファサイズ
    objDfu.setSizeThreshold(1024); 
    // 一時ファイルの保存先フォルダ 
    objDfu.setRepositoryPath(path); 
    // ヘッダの文字エンコーディング
    objDfu.setHeaderEncoding("Windows-31J");  
    try {
      // アップロードされたファイル情報を
      // FileItemオブジェクトのリストとして取得
      List objLst=objDfu.parseRequest(request);
      Iterator objItr=objLst.iterator();
      // リストから順にファイルデータを取り出し、
      // 「/WEB-INF/data/元のファイル名」の形式で
      // アップロードファイルを保存
      while(objItr.hasNext()){
        FileItem objFi=(FileItem)objItr.next();
        if(!objFi.isFormField()){
          // アップロードファイルの元ファイル名を取得
          String strNam=objFi.getName();
          if(strNam!=null && !strNam.equals("")){
            strNam=(new File(strNam)).getName();
            objFi.write(new File(path + "/" + strNam));
          }
        }
      }
    } catch (FileUploadException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
    // 処理後は元のupload.jspにリダイレクト
    response.sendRedirect("upload.jsp");
  }
}


実行結果
実行結果

 upload.jspから投入されたファイルが、アプリケーションルート配下の「/WEB-INF/data」フォルダにアップロード処理されれば成功です。

 アップロード処理の詳細な流れについては、コード中のコメントを確認いただくとして、ここで1点注目していただきたいのは、ファイル名に日本語(2バイト文字)が混在している場合の処理です。ファイル名に日本語が含まれている場合には、そのままではアップロード後にファイル名が文字化けしてしまう可能性があります。必ずDiskFileUpload#setHeaderEncodingメソッドで使用している文字エンコーディング名を指定するのを忘れないようにしてください。

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。