simple HttpURLConnection POST file multipart/form-data from android to google blobstore

前端 未结 4 1772
日久生厌
日久生厌 2020-11-28 05:08

I have very little idea how html works.What i want to do is exactly similar to the following but on android

相关标签:
4条回答
  • 2020-11-28 05:22

    I am using HttpURLConnection to achieve this.

    Create one Multipart custom class ::

    public class MultipartUtility {
        private final String boundary;
        private static final String LINE_FEED = "\r\n";
        private HttpURLConnection httpConn;
        private String charset;
        private OutputStream outputStream;
        private PrintWriter writer;
    
        /**
         * This constructor initializes a new HTTP POST request with content type
         * is set to multipart/form-data
         *
         * @param requestURL
         * @param charset
         * @throws IOException
         */
        public MultipartUtility(String requestURL, String charset)
                throws IOException {
            this.charset = charset;
    
            // creates a unique boundary based on time stamp
            boundary = "===" + System.currentTimeMillis() + "===";
            URL url = new URL(requestURL);
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setUseCaches(false);
            httpConn.setDoOutput(true);    // indicates POST method
            httpConn.setDoInput(true);
            httpConn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + boundary);
            outputStream = httpConn.getOutputStream();
            writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                    true);
        }
    
        /**
         * Adds a form field to the request
         *
         * @param name  field name
         * @param value field value
         */
        public void addFormField(String name, String value) {
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
                    .append(LINE_FEED);
            writer.append("Content-Type: text/plain; charset=" + charset).append(
                    LINE_FEED);
            writer.append(LINE_FEED);
            writer.append(value).append(LINE_FEED);
            writer.flush();
        }
    
        /**
         * Adds a upload file section to the request
         *
         * @param fieldName  name attribute in <input type="file" name="..." />
         * @param uploadFile a File to be uploaded
         * @throws IOException
         */
        public void addFilePart(String fieldName, File uploadFile)
                throws IOException {
            String fileName = uploadFile.getName();
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append(
                    "Content-Disposition: form-data; name=\"" + fieldName
                            + "\"; filename=\"" + fileName + "\"")
                    .append(LINE_FEED);
            writer.append(
                    "Content-Type: "
                            + URLConnection.guessContentTypeFromName(fileName))
                    .append(LINE_FEED);
            writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
            writer.append(LINE_FEED);
            writer.flush();
    
            FileInputStream inputStream = new FileInputStream(uploadFile);
            byte[] buffer = new byte[4096];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            inputStream.close();
            writer.append(LINE_FEED);
            writer.flush();
        }
    
        /**
         * Adds a header field to the request.
         *
         * @param name  - name of the header field
         * @param value - value of the header field
         */
        public void addHeaderField(String name, String value) {
            writer.append(name + ": " + value).append(LINE_FEED);
            writer.flush();
        }
    
        /**
         * Completes the request and receives response from the server.
         *
         * @return a list of Strings as response in case the server returned
         * status OK, otherwise an exception is thrown.
         * @throws IOException
         */
        public List<String> finish() throws IOException {
            List<String> response = new ArrayList<String>();
            writer.append(LINE_FEED).flush();
            writer.append("--" + boundary + "--").append(LINE_FEED);
            writer.close();
    
            // checks server's status code first
            int status = httpConn.getResponseCode();
            if (status == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        httpConn.getInputStream()));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    response.add(line);
                }
                reader.close();
                httpConn.disconnect();
            } else {
                throw new IOException("Server returned non-OK status: " + status);
            }
            return response;
        }
    }
    

    Use it (async way) ::

        MultipartUtility multipart = new MultipartUtility(requestURL, charset);
    
        // In your case you are not adding form data so ignore this
                    /*This is to add parameter values */
                    for (int i = 0; i < myFormDataArray.size(); i++) {
                        multipart.addFormField(myFormDataArray.get(i).getParamName(),
                                myFormDataArray.get(i).getParamValue());
                    }
    
    
    //add your file here.
                    /*This is to add file content*/
                    for (int i = 0; i < myFileArray.size(); i++) {
                        multipart.addFilePart(myFileArray.getParamName(),
                                new File(myFileArray.getFileName()));
                    }
    
                    List<String> response = multipart.finish();
                    Debug.e(TAG, "SERVER REPLIED:");
                    for (String line : response) {
                        Debug.e(TAG, "Upload Files Response:::" + line);
    // get your server response here.
                        responseString = line;
                    }
    
    0 讨论(0)
  • 2020-11-28 05:24

    use okhttp and use following snippet (taken from recipes)

    adjust the header values according to what your server expects.

    private static final String IMGUR_CLIENT_ID = "...";
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
    
    private final OkHttpClient client = new OkHttpClient();
    
    public void run() throws Exception {
    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
        RequestBody requestBody = new MultipartBuilder()
        .type(MultipartBuilder.FORM)
        .addPart(
            Headers.of("Content-Disposition", "form-data; name=\"title\""),
            RequestBody.create(null, "Square Logo"))
        .addPart(
            Headers.of("Content-Disposition", "form-data; name=\"image\""),
            RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
        .build();
    
    Request request = new Request.Builder()
        .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
        .url("https://api.imgur.com/3/image")
        .post(requestBody)
        .build();
    
    Response response = client.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    
    System.out.println(response.body().string());
    }
    
    0 讨论(0)
  • 2020-11-28 05:34

    As alternative you can use Retrofit.

    You can specify a call like this:

    @Multipart
    @POST("/user/photo")
    Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
    

    then create it like this:

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com")
        .build();
    GitHubService service = retrofit.create(GitHubService.class);
    

    and finally execute it like this:

    service.updateUser(Photo, description).enqueue() --> asynchronous

    service.updateUser(Photo, description).execute() --> synchronous

    See the documentation here

    0 讨论(0)
  • 2020-11-28 05:45

    Volley is a good http library for multipart data. AndroidMultiPartEntity class is for progress listener.

        public class AndroidMultiPartEntity extends MultipartEntity
    
        {
    
        private final ProgressListener listener;
    
        public AndroidMultiPartEntity(final ProgressListener listener) {
        super();
        this.listener = listener;
        }
    
        public AndroidMultiPartEntity(final HttpMultipartMode mode, final ProgressListener listener) {
        super(mode);
        this.listener = listener;
        }
    
        public AndroidMultiPartEntity(HttpMultipartMode mode, final String boundary,
        final Charset charset, final ProgressListener listener) {
        super(mode, boundary, charset);
        this.listener = listener;
        }
    
        @Override
        public void writeTo(final OutputStream outstream) throws IOException {
        super.writeTo(new CountingOutputStream(outstream, this.listener));
        }
    
        public static interface ProgressListener {
        void transferred(long num);
        }
    
        public static class CountingOutputStream extends FilterOutputStream {
    
        private final ProgressListener listener;
        private long transferred;
    
        public CountingOutputStream(final OutputStream out,
                                    final ProgressListener listener) {
            super(out);
            this.listener = listener;
            this.transferred = 0;
        }
    
        public void write(byte[] b, int off, int len) throws IOException {
            out.write(b, off, len);
            this.transferred += len;
            this.listener.transferred(this.transferred);
        }
    
        public void write(int b) throws IOException {
            out.write(b);
            this.transferred++;
            this.listener.transferred(this.transferred);
        }
        }
        }
    
        Call the Async task like this
        new UploadFileToServer().execute();
    
    
        The Call method:
        private class UploadFileToServer extends AsyncTask<Void, Integer, String> {
        @Override
        protected void onPreExecute() {
    
            super.onPreExecute();
        }
    
        @Override
        protected void onProgressUpdate(Integer... progress) {
    
        }
    
        @Override
        protected String doInBackground(Void... params) {
    
            return uploadFile();
    
        }
    
        private String uploadFile() {
    
            String responseString = null;
    
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(Config.Seeker_Image_Upload);
    
            try {
                AndroidMultiPartEntity entity = new AndroidMultiPartEntity(new AndroidMultiPartEntity.ProgressListener() {
    
                    @Override
                    public void transferred(long num) {
                        publishProgress((int) ((num / (float) totalSize) * 100));
                    }
                });
    
                File sourceFile = new File(Path);
    
                // Adding file data to http body
                entity.addPart("logo", new FileBody(sourceFile));
    
                // Extra parameters if you want to pass to server
                //entity.addPart("website", new StringBody("www.androidhive.info"));
    
                // String emailaddress = UserActivity.emailaddress;
    
                /*preferences = SeekerProfile.this.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
                email_address = preferences.getString("EMAILADDRESS", "");*/
                entity.addPart("EMAILADDRESS", new StringBody(email_address));
                entity.addPart("OPER", new StringBody(Operation_recruiter_logo_upload));
    
                totalSize = entity.getContentLength();
                httppost.setEntity(entity);
    
                // Making server call
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity r_entity = response.getEntity();
    
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode == 200) {
                    // Server response
                    responseString = EntityUtils.toString(r_entity);
                } else {
                    responseString = "Error occurred! Http Status Code: " + statusCode;
                }
    
            } catch (ClientProtocolException e) {
                responseString = e.toString();
            } catch (IOException e) {
                responseString = e.toString();
            }
    
            return responseString;
    
            }
    
            @Override
            protected void onPostExecute(String result) {
            //Log.e(TAG, "Response from server: " + result);
            enter code here
            }
    
        }
    
    0 讨论(0)
提交回复
热议问题