Java: Binary File Upload using Restlet + Apache Commons FileUpload

浪子不回头ぞ 提交于 2019-12-13 05:42:35

问题


I have a REST API with Restlet 2.3 and need to implement a file-uploading functionality to it. The problem is that, when someone uploads a file using a POST (with a multipart/form-data Content-Type), the file reaches the server with another encoding. To test this, I printed the contents of the original file in a Unix Terminal and then printed it again before parsing the requet with Apache Commons FileUpload (with almost the same code of this example http://restlet.com/technical-resources/restlet-framework/guide/2.2/extensions/fileupload). Both printed contents are very similar, but the original file has less characters, so i assume that my Java server is using the wrong encoding to interpret the file.

The file I sent is a PNG image. With text files the server works perfectly, but when I send photos or any binary file, the problem appears.


回答1:


I don't know how you exactly did to check the received content. First you should check the content type that is used for your file part within the content of your multipart request. You should have something like that for a JPG image:

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

Secondly, I don't know how you actually write the content you received. Apache Commons IO brings an utility method IOUtils.copy that provides a simple solution to write in an OutputStream the content received from an InputStream. See how ti can be used in your context:

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, the encoding aspect only applies for text not for binary content.

Hope it helps, Thierry




回答2:


I actually solved it by using Google's ByteStreams class:

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"));
    }
}



回答3:


I had the similar problem when uploading the image file. This is how I fixed. The problem was in my case the data read from the inputstream. As it is reading from a socket no guarantee that you will have the full buffer of your array filled. Therefore you should check your data size before writing it to the outputbuffer/file. Here is my code hope it helps. Also available in repository 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();
    }        
}


来源:https://stackoverflow.com/questions/28328766/java-binary-file-upload-using-restlet-apache-commons-fileupload

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!