3

I am trying a file upload API using HttpPost and MultipartEntityBuilder. Following is the code I have used.

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(MIME.UTF8_CHARSET);
builder.addBinaryBody(<fileFieldName>, <byteArray>, ContentType.TEXT_PLAIN, <fileName>);

File gets uploaded correctly. But when file name contains non-ASCII characters, it gets uploaded with name "????.jpg". Tried the solution given here https://stackoverflow.com/a/25870301/3271472. But it didn't solve my problem. Please assist.

Community
  • 1
  • 1
Sabitha
  • 273
  • 4
  • 14

5 Answers5

5

This worked for me:

MultipartEntityBuilder b = MultipartEntityBuilder.create();
b.addPart("file", new FileBody(<FILE>, <CONTENTTYPE>, <FILENAME>)).setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
b.setCharset(StandardCharsets.UTF_8);

Just replace <> values with yours...

riva
  • 863
  • 1
  • 7
  • 13
3

builder.setMode(HttpMultipartMode.RFC6532); did the magic in my case. Also check if your server accepts UTF-8 encoded filename. In my case it was Apache Sling Post Servlet and I had to update default server encoding.

    FileBody fileBody = new FileBody(file, ContentType.create("application/pdf"), "Příliš sprostý vtip.pdf");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.setMode(HttpMultipartMode.RFC6532);
    builder.addPart("Příliš sprostý vtip.pdf", fileBody);
    builder.addPart("žabička2", new StringBody("žabička", ContentType.MULTIPART_FORM_DATA.withCharset("UTF-8")));

    HttpEntity entity = builder.build();        
    post.setEntity(entity);
    CloseableHttpClient client = HttpClients.createDefault();
    HttpResponse response = client.execute(post);
Jarda Pavlíček
  • 1,636
  • 17
  • 16
0
  1. can you give name example.
  2. consider using different encoding

Charset

Description

US-ASCII Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set ISO-8859-1 ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1 UTF-8 Eight-bit UCS Transformation Format UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark

0

In case you don't want to cope with a physical file and the idea is to send a request, having already byte[] data (eg. as a MultiPartFile or read from database) you can also forget entirely the fileName argument included in the builder (just leave it as is) and handle the file name separately. Example:

byte[] data = ... // assume it comes from somewhere
String fileName = "Kąśliwa_żółta_jaźń.zip";
MultipartEntityBuilder builder = MultipartEntityBuilder.create().setCharset(StandardCharsets.UTF_8);
builder.addBinaryBody("file", data, ContentType.create(file.getContentType()), fileName);
builder.addPart("name", new StringBody(fileName, ContentType.create("text/plain", StandardCharsets.UTF_8)));

Then on the other side (eg. Spring REST):

@PostMapping("/someUrl")
public ResponseEntity<Void> handle(@RequestParam("file") MultipartFile file, @RequestParam("name") String name) {
   // handle it
}
0

If you want to change file name you can change it with the following code:

 class BackgroundUploader extends AsyncTask<Void, Integer, String> {
        private File file;
        HttpClient httpClient = new DefaultHttpClient();
        private Context context;
        private Exception exception;

        public BackgroundUploader(String url, Long file) {
            this.context = context;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(Void... voids) {
            HttpResponse httpResponse = null;
            HttpEntity httpEntity = null;
            String responseString = null;
            file = new File(selectedFilePath);
            String boundary = "*****";


            try {
                String fileExt = MimeTypeMap.getFileExtensionFromUrl(selectedFilePath);
                Long tsLong = System.currentTimeMillis()/1000;
                final String ts = tsLong.toString().trim() +"."+ fileExt;

                HttpPost httpPost = new HttpPost(AllUrl.Upload_Material);
                MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
                Log.d("checkFile", String.valueOf(file));
                // Add the file to be uploaded
                //multipartEntityBuilder.addPart("file", new FileBody(file));
                multipartEntityBuilder.addPart("file", new FileBody(file, ContentType.MULTIPART_FORM_DATA,ts));
                multipartEntityBuilder.addPart("title",new StringBody("titlep",ContentType.MULTIPART_FORM_DATA));

                // Progress listener - updates task's progress
                MyHttpEntity.ProgressListener progressListener =
                        new MyHttpEntity.ProgressListener() {
                            @Override
                            public void transferred(float progress) {
                                publishProgress((int) progress);
                            }
                        };

                // POST
                httpPost.setEntity(new MyHttpEntity(multipartEntityBuilder.build(),
                        progressListener));


                httpResponse = httpClient.execute(httpPost);
                httpEntity = httpResponse.getEntity();

                int statusCode = httpResponse.getStatusLine().getStatusCode();
                if (statusCode == 200) {
                    // Server response
                    responseString = EntityUtils.toString(httpEntity);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            tvFileName.setText("File Upload completed.\n\n You can see the uploaded file here: \n\n" + "   "+ ts);
                        }
                    });
                } else {
                    responseString = "Error occurred! Http Status Code: "
                            + statusCode;
                }
            } catch (UnsupportedEncodingException | ClientProtocolException e) {
                e.printStackTrace();
                Log.e("UPLOAD", e.getMessage());
                this.exception = e;
            } catch (IOException e) {
                e.printStackTrace();
            }

            return responseString;
        }

        @Override
        protected void onPostExecute(String result) {

            // Close dialog
            dialog.dismiss();
            Toast.makeText(getApplicationContext(),
                    result, Toast.LENGTH_LONG).show();
            //showFileChooser();
        }
        @Override
        protected void onProgressUpdate(Integer... progress) {
            // Update process
            dialog.setProgress((int) progress[0]);
        }
        }


    File file = new File(selectedFilePath);
    Long totalSize = file.length();

    new BackgroundUploader(selectedFilePath,totalSize).execute();
}
Prakash
  • 69
  • 7
  • I would consider looking at how to use the formatting tools. You can enclose this into a block of code [Meta Stack Exchange](https://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks) – Mr00Anderson Apr 05 '19 at 15:39
  • i have used implementation group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1' implementation('org.apache.httpcomponents:httpmime:4.3') { exclude module: "httpclient" } for use of MultipartEntityBuilder class entity – Prakash Apr 08 '19 at 07:41