Java:使用Restlet + Apache Commons FileUpload进行二进制文件上载

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java:使用Restlet + Apache Commons FileUpload进行二进制文件上载相关的知识,希望对你有一定的参考价值。

我有一个REST API与Restlet 2.3,需要实现文件上传功能。问题是,当有人使用POST(具有multipart / form-data Content-Type)上传文件时,该文件将使用其他编码到达服务器。为了对此进行测试,我在Unix终端中打印了原始文件的内容,然后在使用Apache Commons FileUpload解析requet之前再次打印它(与此示例http://restlet.com/technical-resources/restlet-framework/guide/2.2/extensions/fileupload的代码几乎相同)。两个打印的内容非常相似,但原始文件的字符较少,所以我假设我的Java服务器使用错误的编码来解释文件。

我发送的文件是PNG图像。使用文本文件服务器可以正常工作,但是当我发送照片或任何二进制文件时,会出现问题。

答案

我不知道你是如何检查收到的内容。首先,您应该检查多部分请求内容中用于文件部分的内容类型。对于JPG图像,你应该有类似的东西:

-----------------------------75956101888331271337088331
Content-Disposition: form-data; name="fileToUpload"; filename="myimage.jpg" 
Content-Type: image/jpeg

其次,我不知道你是如何写出你收到的内容的。 Apache Commons IO带来了一个实用方法IOUtils.copy,它提供了一个简单的解决方案,用于在OutputStream中写入从InputStream收到的内容。了解如何在您的上下文中使用ti:

while (fileIterator.hasNext()) {
    FileItemStream fi = fileIterator.next();
    if (fi.getFieldName().equals("fileToUpload")) {
        FileOutputStream fos = new FileOutputStream(
              "output"+File.separator+fi.getFieldName());
        IOUtils.copy(fi.openStream(), fos);
        fos.close();
    }
}

IMO,编码方面仅适用于不是二进制内容的文本。

希望它有所帮助,蒂埃里

另一答案

我实际上是通过使用Google的ByteStreams类来解决它的:

while (fileIterator.hasNext()) {
    FileItemStream fi = fileIterator.next();
    if (fi.getFieldName().equals(FILE_TO_UPLOAD)) {
        byte[] byteArray = ByteStreams.toByteArray(fi.openStream());
        result = new String(byteArray,Charset.forName("ISO-8859-1"));
    }
}
另一答案

上传图像文件时遇到了类似的问题。这是我修复的方式。在我的例子中,问题是从输入流读取的数据。因为它是从套接字读取,不能保证您将填充数组的完整缓冲区。因此,在将数据写入outputbuffer / file之前,应检查数据大小。这是我的代码希望它有所帮助。也可以在存储库https://github.com/esabilbulbul/java-servlet-fileupload/blob/master/README.md中找到

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
upload.setHeaderEncoding("UTF-8");

// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) 
{
    FileItemStream item = iter.next();
    String name = item.getFieldName();

    //InputStream attachmentStream = item.openStream();
    //byte[] attachmentBytes = ByteStreams.toByteArray(attachmentStream);


    //InputStream stream = item.getInputStream();
    InputStream stream = item.openStream();

    if (item.isFormField()) 
    {
        //System.out.println("Form field " + name + " with value " + Streams.asString(stream) + " detected.");
    }
    else
    {
        System.out.println("File field " + name + " with file name "+ item.getName() + " detected.");

        // Process the input stream
        FileOutputStream fout= new FileOutputStream ("c:\" + item.getName());
        BufferedOutputStream bout= new BufferedOutputStream (fout);
        BufferedInputStream bin= new BufferedInputStream(stream);
        byte buf[] = new byte[2048];
        int len=0;
        while ((len = bin.read(buf)) > 0)//((bin.read(buf)) != -1)
        {
            bout.write(buf, 0, len);
            if (len<2048)
                len = len;
        }
        bout.close();
        bin.close();
    }        
}

以上是关于Java:使用Restlet + Apache Commons FileUpload进行二进制文件上载的主要内容,如果未能解决你的问题,请参考以下文章

java容器都有哪些 restlet

使用 Guice 实现 Restlet

在 OSGi 中从 Restlet 启动 Jetty

通过 OAuth 访问 NetSuite RESTlet

GWT 中的 RESTLET -RPC CALL

Restlet 2.0.8:单个restlet应用程序实例的多种身份验证方法(BASIC、DIGEST)?