0

Android から Jersey を実行している Tomcat サーバーにファイルをアップロードしようとしています。Post Request 内にパッケージ化しています。

これは私がAndroidで行うことです:

protected String doInBackground(String... params) {
    String url = params[0];
    String pathToFile = params[1];
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost();
    HttpResponse response = null;
    httpPost.addHeader("Cookie", "sessionToken=~session");
    try {
        httpPost.setURI(new URI(url));
        httpPost.setHeader("Accept", "application/json");
        MultipartEntity entity = new MultipartEntity(
                HttpMultipartMode.BROWSER_COMPATIBLE);
        File file = new File(pathToFile);
        if(!file.exists())
            return null;
        FileBody fileBody = new FileBody(file);
        entity.addPart("file", fileBody);
        httpPost.setEntity(entity);

        response = httpClient.execute(httpPost);
        HttpEntity result = response.getEntity();
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch(Exception e){
        e.printStackTrace();
    }
    return response.getStatusLine().toString();

サーバーには次のものがあります。

「org.jvnet.mimepull.DataHead$ReadMultiStream」タイプの InputStream を受け取り、読み取り中にファイルの最後に到達した後、読み取りが 1024 に戻ります。

@POST
@Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces({ MediaType.APPLICATION_JSON })
public Response uploadStorageFile(@Context UriInfo ui, @Context HttpHeaders hh, @FormDataParam("file") 
InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail){
    System.out.println(uploadedInputStream.getClass().getName());
    String uploadedFileLocation = fileDetail.getFileName();
    long size = fileDetail.getSize();
    // save it
    writeToFile(uploadedInputStream);

    String output = "File uploaded to : ";

    return Response.status(200).entity(output).build();

}
private void writeToFile(InputStream uploadedInputStream) {

        try {
            OutputStream out = new FileOutputStream(new File("test.jpg"));
            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = uploadedInputStream.read(bytes)) > 0) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

ファイルの長さが 8192 の場合、サイクルは次のようになります: 1024,2048,3072,4096,5120,6144,7168,8192,1024 -> なぜ?

注: -1 の条件で試しました。

誰が何が起こっているのか理解できますか?

4

2 に答える 2

2

それが問題の解決に役立ったので、最新のコメントは、このバグが原因であったことを示しています。

ReadMultiStream クラスの両方のメソッド「読み取り」は、実装されたインターフェース java.io.InputStream の規約に違反しています。Javadoc は、ストリームの最後に -1 を返す必要があると述べていますが、ReadMultiStream クラスは最初の呼び出し (ストリームの最後) に対してのみ -1 を返し、後続のすべての呼び出しは代わりに例外をスローします。この問題は、Web サービスを介して文字のストリームを送信し、それをクライアント側の java.io.BufferedReader にラップすることでシミュレートできます。ストリームが改行文字で終わらない場合、メソッド readLine の通常の使用は失敗します。

修正バージョン: 2.2.6

于 2013-07-25T15:44:07.370 に答える
1

@Jonathan Drapeau、@ boxed |に感謝します。問題が特定されました。ReadMultiStream は、java.io.InputStream インターフェイスに違反しています。

解決策はかなり単純で、サーバー側でした:

@POST
@Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces({ MediaType.APPLICATION_JSON })
public Response uploadStorageFile(@Context UriInfo ui, @Context HttpHeaders hh,     @FormDataParam("file") 
InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail){
System.out.println(uploadedInputStream.getClass().getName());
String uploadedFileLocation = fileDetail.getFileName();
long size = fileDetail.getSize();
// save it
try {
            //test.jpg for test purposes
    OutputStream out = new FileOutputStream(new File("test.jpg")); 
    IOUtils.copy(uploadedInputStream, out);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

String output = "File uploaded to : ";

return Response.status(200).entity(output).build();

}

質問で提供したように、複数のチュートリアルで入力ストリーム (サーバー側) を操作するように教えていました。このため、最近のバグかどうかはわかりません。

于 2013-07-26T08:46:15.173 に答える