<< September/2010
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
>>
この記事は旧Blogで書いた記事の再掲です
元の日時は「2007/01/25 13:12:44」です




さて前編の続きだ

multipart/form-data形式のリクエストを、
Javaクラス内から発行する方法を考えるわけだが、
前回は既存のモジュールをあれこれいじって結局失敗

こうなれば最後の手段、「力技」で勝負である

要は、HTTPリクエストの実態は文字列の通信だから、
リクエストに文字列を仕様通りに流し込めばいいわけだ

とはいえ、自力で書いたコードは、
どうにもmultipartと認識されなかったので、
さらに細かくWebで調べたら、「JavaHouse」にコードがあった

このコードのままでは動かなかったので、
少し手を入れたのが以下のコードである

※「Parameter」はnameとvalueをセットしただけのモデル
※「TransportFile」は、nameとFileクラスをセットしただけのモデル
※「BOUNDARY」は適当な半角英数文字列

※「¥r」がなぜか表示されなかったので全角にしているが、実際は半角

/**
* multipartデータ出力。
* @param con HTTPコネクション
* @throws IOException
*/
void sendMultipart(HttpURLConnection con) throws IOException {
    
  // multipart/form-data形式
  con.setRequestProperty("Content-type",
      "multipart/form-data;  boundary=" + BOUNDARY);
    

  // データストリームオープン
  DataOutputStream out = new DataOutputStream(con.getOutputStream());
      
  // MultiPartのデータ作成
  // 文字部分
  for (int i = 0; i < this.paramList.size(); i++) {
    Parameter param = this.paramList.get(i);

    out.writeBytes("--" + BOUNDARY + "¥r\n");
    out.writeBytes("Content-Disposition: form-data; ");
    out.writeBytes("name=\"" + param.getName() + "\"¥r\n");
    out.writeBytes("¥r\n");

    byte[] byteBuf = param.getValue().getBytes();
    for (int j = 0; j < byteBuf.length; j++) {
      out.writeByte(byteBuf[j]);
    }
    out.writeBytes("¥r\n");
  }
      
  // ファイル部分
  BufferedInputStream in = null;
  for (int i = 0; i < this.fileList.size(); i++) {
    TransportFile file = this.fileList.get(i);

    in = new BufferedInputStream(
        new FileInputStream(file.getFile()));

    out.writeBytes("--" + BOUNDARY + "¥r\n");
    out.writeBytes("Content-Disposition: form-data; ");
    out.writeBytes("name=\"" + file.getParamName() + "\"; ");
    out.writeBytes("filename=\"" + file.getFileName() + "\"¥r\n");

    out.writeBytes("Content-Type: application/octet-stream¥r\n");
    out.writeBytes("¥r\n");

    int fileInt = 0;
    while ((fileInt = in.read()) != -1) {
      out.writeByte(fileInt);
    }
    in.close();
    out.writeBytes("¥r\n");
  }
      
  // ラスト
  out.writeBytes("--" + BOUNDARY + "--");
  out.flush();
  out.close();
}

とあるクラスのメソッドだけ引っこ抜いたので、
一部不明なところがあるが、なんとなくわかるのではないだろうか

私が詰まったのは2点

・BOUNDARYの前に"--"が必要だと気づかなかった
 (仕様を解説するサイトのほとんどがBOUNDARYを"------..."とか書いていて勘違い)

・最後に「"--" + BOUNDARY + "--"」を出力してなかった


まあ、今回のことでわかったのは、
やっぱり最後に頼れるのは仕様書と力技、ということか

ちなみに当然ながら、この仕様通りにparseすれば、
multipartのリクエストを受け取ることもできるはず
「Jakarta Commons FileUpload」を使いたくない方はお試しを

[ Web技術::Java ] comments (2) trackback (0)
すでにこちらのBlogは更新しておりませんでしたので、
回答が遅れまして申し訳ありません
(すでにご覧になってないとは思いますが・・・)

元記事が2年以上前なのと、最近はJavaメインではないので、
詳しくは覚えてないのですが、
だいたい以下のような感じだったかと

 getParamName : inputタグのnameに相当
 getFileName : input type=fileで指定されるファイル名に相当

可能であれば、実際に試されることをおすすめします
| ぱろっと | mail | url | 2010.03.02 (Tue) 0:42 |
参考にさせていただいております。

質問なのですが、
TransportFile.getParamName()

TransportFile.getFileName()
で取得される値の違いはなんでしょうか?

回答いただければ幸いです。
| ボンバー | mail | url | 2010.02.05 (Fri) 14:37 |









http://www.parrot-studio.com/studiwo/tb.php/90
NEW ENTRIES
RECENT COMMENTS
CATEGORIES
ARCHIVES
LINK
PROFILE
POWERED BY
 Script by ⇒ BLOGN+(ぶろぐん+)
 Skin by ⇒ vivid*face
OTHER
SEARCH
LOGIN
現在のモード: ゲストモード
ID:
PASS:
AdSense

<NEXT  PAGETOP  BACK>