8

HttpURLConnectionファイルをサーバーに送信するために使用するAndroidのクライアントアプリケーションがあります。サーバーは、Apache Commons FileUpload API を使用してフォームデータ値を解析します。

は次のHttpURLConnection要求を送信します。

-----------------------------4912995119421
Content-Disposition: form-data; name="deviceid"

9428103
-----------------------------4912995119421
Content-Disposition: form-data; name="countryid"

598
-----------------------------4912995119421
Content-Disposition: form-data; name="number"

98621360
-----------------------------4912995119421
Content-Disposition: form-data; name="file"; filename="2012-12-08 17.42.18.jpg"
Content-Type: image/jpeg

ÿØÿá1 Exif  II*    
      @      °      ª    
   ²              ¼       Ä   (       1    Ì   2    Ø          i‡    ì   %ˆ    \  n  SAMSUNG GT-S5360L H      H      S5360LUHLB1 2012:12:08 17:42:18  š‚    î  ?‚    ö  "ˆ       'ˆ    È    ?    0220?    þ  ?      ‘     ’    &  ’       
’    .        0100             @       °       >  £       ¤        ¤        ¤    6  ¤                     
   2012:12:08 17:42:18 2012:12:08 17:42:18    
     d               R98      0100                         (           ¤      T.      ÿØÿà JFIF      ÿÛ C @@ÿÛ 
-----------------------------4912995119421--

サーバーコード:

    String contentType = request.getContentType();
    if ((contentType.indexOf("multipart/form-data") == -1)) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }


    long maxFileSize = (2 * 1024 * 1024);

    int maxMemSize = (2 * 1024 * 1024);

    DiskFileItemFactory factory = new DiskFileItemFactory();
    // maximum size that will be stored in memory
    factory.setSizeThreshold(maxMemSize);

    // Create a new file upload handler
    ServletFileUpload upload = new ServletFileUpload(factory);
    // maximum file size to be uploaded.

    upload.setSizeMax(maxFileSize);

    List fileItems = upload.parseRequest(request);
    Iterator i = fileItems.iterator();


    //leo primero todas las variables.

    int deviceID = 0;
    int countryID = 0;
    String phoneNumber = "";



    while (i.hasNext()) {
        FileItem fi = (FileItem) i.next();

        if (fi.isFormField()) {
            String variable = fi.getFieldName();
            if (variable.equals("deviceid")) {
                deviceID = Integer.parseInt(fi.getString());
            } else if (variable.equals("countryid")) {
                countryID = Integer.parseInt(fi.getString());
            } else if (variable.equals("number")) {
                phoneNumber = String.valueOf(Long.parseLong(fi.getString()));
            }

        }

    }

    if (deviceID == 0 || countryID == 0 || phoneNumber.equals("")) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

問題は行にありList fileItems = upload.parseRequest(request);ます。返されたリストは空で、フォーム データの値を取得できません。

4

5 に答える 5

29

事前にリクエスト本文を(暗黙的に)解析している場合は、その時点で空になります。HTTP リクエスト本文は、 1 回だけ読み取り/解析できます(クライアントが送信したのは 1 回だけで、複数回送信することはないため)。

Commons FileUpload にリクエストを送信するに、次のメソッドのいずれかを呼び出した場合、リクエストの本文は暗黙的に読み取られ、解析されます。

request.getParameter();
request.getParameterMap();
request.getParameterNames();
request.getParameterValues();
request.getReader();
request.getInputStream();

これらのメソッドを事前に呼び出していないことを完全に確認する必要があります(すべてのサーブレット フィルターも確認してください)。

それを行っていないことをすでに確認している場合、考えられる他の唯一の原因は、境界ヘッダーが正しくないか、改行が正しくないことです (実際には CR+LF である必要があり、LF だけではありません)。java.net.URLConnection を使用して HTTP 要求を起動および処理するの下部の「ファイルのアップロード」セクションに、具体的で適切な例があります。

于 2012-12-14T15:16:02.773 に答える
0

私もこの問題に遭遇していましたが、リクエスト オブジェクトの読み取りに特に関連するものは見つかりませんでした。このブロックを削除することで、最終的に機能するようになりました。

@MultipartConfig(
    location="/tmp", 
    fileSizeThreshold=1024*1024, 
    maxFileSize=1024*1024*5, 
    maxRequestSize=1024*1024*5*5
)

getParts() を使用してリクエストを読み取ろうとしたときに、これを削除するのを忘れていたようです。私はJavaに少し慣れていないので、これがServletFileUpload#parseRequestと競合することを知りませんでした。とにかく、それを取り除くと、parseRequest は正しく配列を返しました。

于 2013-08-23T22:51:52.837 に答える