S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

Tomcat 5.5.23
Jakarta Commons fileupload 1.2
Jakarta Commons httpclient 3.0.1

USBカメラで撮影した画像ファイルをServletに送りたい訳だけど。
一緒に撮影した人のキー項目を送りたいのに、普通にPOSTのパラメータじゃ送れない。
POSTの場合、ContentTypeが"x-www-form-urlencoded"でないとパラメータが取得できない?
ってServletの仕様?なんじゃそりゃ?
んなこと言うんなら、パラメータ1つ1つをMultipartの1つ1つのパートにしちゃる。
同じようなこと考えてる人いるし。
データ量を考えるとマイナスだけど、所詮「名前」と「値」のテキストだし、大量のリクエストが発生する訳でもないし。
なんとなく、下記のようなコードで実現可能な感じ。


【クライアント側】

String id;        // サーバに送信したいID
String date;      // サーバに送信したい日付
byte [] binary;   // サーバに送信したいバイナリイメージ
String fileName;  // バイナリイメージのファイル名

// HTTPクライアントの生成
HttpClient client = new HttpClient();

// POSTメソッドのオブジェクトを生成
PostMethod method = new PostMethod("http://xxx.yyy.zzz/hogehoge");

// 従来のパラメータ設定
method.setParameter("paramId", id);
method.setParameter("paramDate", date);

// Partの個数が明確にならないかもしれないのでListにしておく
List partsList = new ArrayList();

// パラメータをMutipartのPartにする
NameValuePair [] pairs = getPostMethod().getParameters();
for ( int i = 0 ; i < pairs.length ; i++ ) {
 partsList.add(new StringPart(pairs[i].getName(), pairs[i].getValue(), "iso-8859-1"));
}

// サーバへ送信するバイナリイメージをPartにする
ByteArrayPartSource source = new ByteArrayPartSource("photo.jpg", binary);
partsList.add(new FilePart("paramPhoto", source));

// PartをMultipartRequestEntityにして
Part [] parts = new Part [getPartList().size()]; 
partsList.toArray(parts);
method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams()));

// リクエスト送信
int resCode = client.executeMethod(method);


【サーバ側】

protected void doPost(HttpServletRequest req, HttpServletResponse res)
				 throws ServletException, IOException {

    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload fileUpload= new ServletFileUpload(factory);

    try {

        List list = fileUpload.parseRequest(req);

        String id;
        String date;
        byte [] binary;

        if ((list == null) || (list.size() == 0)) {

            // 従来どおりのパラメータ取得
            id= req.getParameter("paramId");
            date= req.getParameter("paramDate");

        } else {

            for ( int i = 0 ; i < list.size() ; i++ ) {

                FileItem item = (FileItem) list.get(i);

                if ("paramId".equals(item.getFieldName())) {

                    id = item.getString();

                } else if ("paramDate".equals(item.getFieldName())) {

                    date = item.getString();

                } else if ("paramPhoto".equals(item.getFieldName())) {

                    binary = item.get();

                }

            }

      // 取得したバイナリイメージをファイルやDBに書き出すような処理

        }

    } catch (Exception e) {

        e.printStackTrace();

    }

}

■参考サイト

FORMデータとエンコーディング
http://homepage1.nifty.com/algafield/core1.html

HttpClient query...
http://www.mail-archive.com/commons-httpclient-dev@jakarta.apache.org/msg07460.html

ファイルアップロード "multipart/form-data" 処理のときに正しくパラメータを受け取るには
http://www.ecoop.net/memo/2005-06-18-1.html