1

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 = "\r\n";
        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["mime"] . ".";
    } else {
        $item->file_status = "File is not an image.";
    }

$item->imageFileType = $imageFileType;
$item->file_check = $check;

$results_array['msg'] = 'Test';
$results_array['status'] = false;
$results_array['result'] = $item;

echo $ws->unicodeString(json_encode(array('posts'=>($results_array))), 'UTF-8');

Parameter receive successfully with file, But Remember attachmentFileName if full file path .

6
  • What is the response code you are getting? Commented Mar 7, 2016 at 8:32
  • Check output even for other response code so that you can get more detail of the error. Commented Mar 7, 2016 at 8:39
  • @Exception it's 200, Problem is passing Parameters With Image File To Server Commented Mar 7, 2016 at 10:50
  • You have formulated the request body wrong buddy :) thats why your image is not getting detected at server :) did you read the blog I posted?? Commented Mar 7, 2016 at 12:11
  • problem was using con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); and after remove it, i can't upload file Commented Mar 7, 2016 at 13:00

1 Answer 1

9

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 :)

Sign up to request clarification or add additional context in comments.

10 Comments

it only send image to server, i want to send Parameters and Image
@AndroSco if you have seen the code correctly you will notice that I am creating two sections in message body. First section in message body has "Content-Type: image/jpeg" + crlf and image content in binary :) and the second part has a parameter named testName :) So I am sending two things one is image and a string which is the name of the person
I wanted you to read it because I wanted you to understand the structure of multipart message body :) There are certain issues I found in your code lemme point out :) might help you :)
I am updating my anser now please have look
Just see the message template carefully, the one I posted from firefox and create your request body similarly (look into my code for reference like (twoHyphens + boundary + lineEnd all those things I wrote) believe me once you get it, you can write it very easily :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.