0

我正在尝试将文件从 Android 上传到运行 Jersey 的 Tomcat 服务器。我将它打包在一个发布请求中。

这就是我在 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 回答