Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
435 views
in Technique[技术] by (71.8m points)

post - Send File And Parameters To Server With HttpURLConnection in android API 23

After many tries I Solved it, there is the code i use to send parameters and image :

    public class PurchaseAsync extends AsyncTask<String, Void, Boolean> {

    public static final String TAG = PurchaseAsync.class.getSimpleName();
    public PurchaseAsync(ArrayList<CustomItem> parameters, String imageAddress, PurchaseListener listener){
        this.parameters = parameters;
        this.imageAddress = imageAddress;
        this.listener = listener;
        if(this.parameters == null){
            this.parameters = new ArrayList<>();
        }
        LTH.dLog(WMH.WEBSERVICE, TAG + " -> Image path : " + imageAddress);
    }
    private String imageAddress = "";
    // ========== Use HashMap, it works similar to NameValuePair
    ArrayList<CustomItem> parameters = new ArrayList<>();
    private PurchaseListener listener;
    public interface PurchaseListener {
        void execute(int exception, Boolean success, FactorItem msg);
    }
    private int customException = WMH.NO_EXCEPTION;
    private FactorItem msg = new FactorItem();
    @Override
    protected void onPreExecute() {
        progressDialog = ProgressDialog.show(App.getActivity(),
                "", App.getContext().getString(R.string.pb_msg_purchase_request), true, false);
        progressDialog.setCanceledOnTouchOutside(false);
        super.onPreExecute();
    }
    private ProgressDialog progressDialog;
    @Override
    protected void onPostExecute(Boolean success) {
        super.onPostExecute(success);
        if(progressDialog != null){
            progressDialog.dismiss();
        }
        LTH.dLog(WMH.WEBSERVICE, TAG + " -> customException : " + customException + " , Success : " + success);
        if(listener != null){
            listener.execute(customException, success, msg);
        }
    }

    @Override
    protected Boolean doInBackground(String... strings) {
        customException = WMH.NO_EXCEPTION;
        try{
            String strResult = readData(strings[0]);
            if(strResult.equals("")){
                customException = customException == WMH.NO_EXCEPTION ? WMH.INVALID_EXCEPTION : customException;
                return false;
            }else{
                JSONObject jsonObject = jsonParser(strResult);
                if(jsonObject == null){
                    customException = customException == WMH.NO_EXCEPTION ? WMH.INVALID_EXCEPTION : customException;
                    return false;
                }
                pareFactor(jsonObject);
                if (jsonObject.has("status")) {
                    return jsonObject.getBoolean("status");
                } else {
                    customException = customException == WMH.NO_EXCEPTION ? WMH.INVALID_EXCEPTION : customException;
                    return false;
                } // end of else/if
            }
        }catch (Exception e){
            customException = customException == WMH.NO_EXCEPTION ? WMH.INVALID_EXCEPTION : customException;
            LTH.eLog(WMH.JSON, TAG + " -> Exception Error In Json: " + e.getMessage(), e);
        }
        return false;
    }
    private void pareFactor(JSONObject iJsonObject) throws Exception{
        if (iJsonObject.has("result")) {
            if(iJsonObject.get("result") == null){
                return;
            }
            if(!(iJsonObject.get("result") instanceof JSONObject)){
                return;
            }
            JSONObject jsonObject = iJsonObject.getJSONObject("result");
            if(jsonObject.has("code")){
                String code = jsonObject.getString("code");
                msg.setCode(code);
                int fid;
                try {
                    fid = Integer.parseInt(jsonObject.getString("fid"));
                }catch (NumberFormatException nfe){
                    fid = 0;
                    // throw new Exception("Factor ID Not Assigned Correctly");
                }
                msg.setItemId(fid);
                if(jsonObject.has("price_number")) {
                    String price_number = jsonObject.getString("price_number");
                    msg.setPayment(price_number);
                    msg.setTotal(price_number);
                }
                if(jsonObject.has("price")) {
                    int price;
                    try {
                        price = Integer.parseInt(jsonObject.getString("price"));
                    }catch (NumberFormatException nfe){
                        price = 0;
                        // throw new Exception("Factor ID Not Assigned Correctly");
                    }
                    msg.setPaymentPrice(price);
                    msg.setTotalPrice(price);
                }
            }
        } else {
            throw new Exception("Factor Information Not Assigned");
        }
    }
    private JSONObject jsonParser(String strData) throws Exception{
        if(!strData.equals("")){
            JSONObject jsonObject = new JSONObject(strData);
            return jsonObject.getJSONObject("posts");
        }
        return null;
    }
    private String readData(String strUrl){
        LTH.dLog(WMH.WEBSERVICE, TAG + " -> readData, Address : " + strUrl);
        // ========== Server Communication part - it's relatively long but uses standard methods
        // ========== Encoded String - we will have to encode string by our custom method (Very easy)
        String outPut = "";
        String attachmentName = "image";
        String attachmentFileName = "";
        String crlf = "
";
        String twoHyphens = "--";
        String boundary = "*****";
        int bytesRead = 0, bytesAvailable, bufferSize;
        int maxBufferSize = WMH.MAX_BUFFER_SIZE;
        /*if(imageAddress.contains("/")){
            attachmentFileName = imageAddress.substring(imageAddress.lastIndexOf("/")+1, imageAddress.length());
        }*/
        attachmentFileName = imageAddress;
        LTH.dLog(WMH.WEBSERVICE, TAG + " -> Attachment Name : " + attachmentName);
        try{
            HttpURLConnection httpUrlConnection = null;
            URL url = new URL(strUrl);
            httpUrlConnection = (HttpURLConnection) url.openConnection();
            httpUrlConnection.setUseCaches(false);
            httpUrlConnection.setDoInput(true);
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setRequestMethod("POST");
            // httpUrlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36");
            httpUrlConnection.setRequestProperty("Connection", "Keep-Alive");
            httpUrlConnection.setRequestProperty("Cache-Control", "no-cache");
            httpUrlConnection.setRequestProperty("ENCTYPE", "multipart/form-data");
            httpUrlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            if(imageAddress.length() > 4) {
                httpUrlConnection.setRequestProperty(attachmentName, attachmentFileName);
            }
            DataOutputStream request = new DataOutputStream(httpUrlConnection.getOutputStream());
            request.writeBytes(twoHyphens + boundary + crlf);
            if(imageAddress.length() > 4) {
                request.writeBytes("Content-Disposition: form-data; name="" + attachmentName + "";filename="" + attachmentFileName + """ + crlf);
                request.writeBytes("Content-Type: image/*" + crlf);
                request.writeBytes(crlf);

                /*BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                Bitmap bitmap = BitmapFactory.decodeFile(imageAddress, options);
                byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
                for (int i = 0; i < bitmap.getWidth(); ++i) {
                    for (int j = 0; j < bitmap.getHeight(); ++j) {
                        //we're interested only in the MSB of the first byte, since the other 3 bytes are identical for B&W images
                        pixels[i + j] = (byte) ((bitmap.getPixel(i, j) & 0x80) >> 7);
                    }
                }
                request.write(pixels);*/

                // Code ...
                FileInputStream fileInputStream = new FileInputStream(attachmentFileName);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                byte[] buffer = new byte[bufferSize];

                // read file and write it into form...
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0) {

                    request.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                }
                // Code .

                request.writeBytes(crlf);
                request.writeBytes(twoHyphens + boundary + crlf);
            }

            // Added To Send Parameters
            for(int i=0; i<parameters.size();i++){
                String key = parameters.get(i).getTitle();
                String value = "";

                try {
                    value = URLEncoder.encode(parameters.get(i).getContent(), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    LTH.eLog(TAG, e.getMessage(), e);
                    value = parameters.get(i).getContent();
                }

                LTH.dLog(WMH.WEBSERVICE, TAG + " -> " + key + " : " + value);
                request.writeBytes("Content-Disposition: form-data; name=""+key+""" + crlf);
                request.writeBytes(crlf);
                request.writeBytes(value);
                request.writeBytes(crlf);
                request.writeBytes(twoHyphens + boundary + crlf);
            }

            // request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);

            request.flush();
            request.close();

            int responseCode = httpUrlConnection.getResponseCode();
            LTH.dLog(WMH.WEBSERVICE, TAG + " -> Response Code : " + responseCode + " , Response Message : " + httpUrlConnection.getResponseMessage());
            if (responseCode == HttpsURLConnection.HTTP_OK) {
                InputStream responseStream = new BufferedInputStream(httpUrlConnection.getInputStream());

                BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream, Charset.forName("UTF-8")));

                String line = "";
                while ((line = responseStreamReader.readLine()) != null) {
                    outPut+=line;
                }
                responseStreamReader.close();
            }

            httpUrlConnection.disconnect();
        } catch (Exception exception){
            LTH.dLog(WMH.WEBSERVICE, TAG + " -> Error String OUTPUT Result : " + exception.getMessage(), exception);
            return exception.toString();
        }
        LTH.dLog(WMH.WEBSERVICE, TAG + " -> String OUTPUT Result : " + outPut);
        return outPut;
    }
}

php :

    $item = new stdclass();
    $item->image = $_FILES['image'];

    $imageFileType = pathinfo($_FILES['image'],PATHINFO_EXTENSION);
    $check = getimagesize($_FILES['image']["tmp_name"]);
    if($check !== false) {
        $item->file_status = "File is an image - " . $check["mi

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I have written a blog on Multipart request in Android. I have clearly explained the structure of the multipart request, what every single text in the body means, how to construct one on your own in android (with code) and also how it resembles with the one that gets generated automatically when you hit the post service from browsers like firefox and finally how to consume the webrequest in JSP and java rest API. Have a glance :) Is Multipart request complicated? Think again.

EDIT

First thing first :) As name suggests multipart form data is nothing but a single request containing multiple parts in it :) Example: here is a multipart request generated by firefox :)

------WebKitFormBoundaryQHJL2hsKnlU26Mm3
Content-Disposition: form-data; name="profilePic"; filename="66.jpg"
Content-Type: application/octet-stream

//your image data appears here
------WebKitFormBoundaryQHJL2hsKnlU26Mm3
Content-Disposition: form-data; name="testingName"

Myfile.jpg //file name sent as parameter you can pass whatever parameter you want :)
------WebKitFormBoundaryQHJL2hsKnlU26Mm3--

Can you see that??? There are two parts one contains a jpg file and other contains a string (form data) :)

In your case one part will contain the image and others will contain the rest of the parameters. So in order to inform the server which part contains what you will have to create request in proper format :) In your case first part lets assume image so.

DataOutputStream dos = new DataOutputStream(con.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);

dos.writeBytes("Content-Disposition: form-data; name="image";filename="" + imageAddress +""" + lineEnd);

dos.writeBytes("Content-Type: image/jpeg" + lineEnd);
dos.writeBytes(lineEnd);
dos.write(byteArray);//your image array here buddy
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name="your parameter name"" + crlf);
dos.writeBytes(lineEnd);
dos.writeBytes(testName);//your parameter value
dos.writeBytes(lineEnd); //to add multiple parameters write Content-Disposition: form-data; name="your parameter name"" + crlf again and keep repeating till here :)
dos.writeBytes(twoHyphens + boundary + twoHyphens);
dos.flush();
dos.close();

Did you see what you were missing yes its content-type :) afterspecifying content-type you will need to enter a line end (can you see the firefox generated multipart form request)

After specifying image content you need to start the second section so enter the new line again :) Then specify the beginning of new section with twoHyphens + boundary + crlf Specify the content type again :) with Content-Disposition: form-data; name="your parameter name

Enter the new line add the parameter and enter the new line again and close the section with new line again.

Repeat it untill you add all your parameter (seriously I prefer creating json of all parameter and sending it as one section) and then close multipart request with twoHyphens + boundary + twoHyphens

Thats it :) Did you get your error now?? :)

Summary : You will have to create a multipart-formdata request in such a way that it exactly matches the structure of the multipart-formdata I posted from fire fox browser :)

So if you see whatever the code I posted am doing nothing more than following the template and adding texts as per the template :) believe me server under stands it because browsers wont make mistakes you know :)

Still have a doubt ask me :) am here to help. And the code above I pasted isn't just a logical one its actually from the working code :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...