0

Im trying to send a postRequest using httpUrlConnection instead of using httpClient. The API that i am trying to access gave an implementation that used httpclinet that i can't use because it is now deprecated. I thought I had done the same thing using the urlConnection but I keep getting the error that no image has been sent (and that I have to make sure the POST request I'm sending matches the documentation).

This is the code provided by the API I am using.

public static String upload(String path) throws IllegalStateException, JSONException, IOException {


    String urlString = "http://www.bitocr.com/api";
    File file = new File(path);
    HttpClient httpClient = HttpClientBuilder.create().build();
    HttpPost postRequest = new HttpPost(urlString);

    // build request parameters
    StringBody apiKey = new StringBody("apikey", ContentType.MULTIPART_FORM_DATA);
    StringBody lang = new StringBody("en", ContentType.MULTIPART_FORM_DATA);
    FileBody fileBody = new FileBody(file, ContentType.MULTIPART_FORM_DATA);

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addPart("apikey", apiKey);
    builder.addPart("lang", lang);
    builder.addPart("file", fileBody);

    postRequest.setEntity(builder.build());
    HttpResponse res = null;

    // execute the request
    res = httpClient.execute(postRequest);

    JSONObject jsonObject = new JSONObject();
    if (res != null) {

        jsonObject = new JSONObject(IOUtils.toString(res.getEntity().getContent(), "UTF-8"));
        String error = jsonObject.get("error").toString();
        if (error.equals("0")) {
            // success
            System.out.println(jsonObject.getString("result"));
        } else {

            System.out.println("Error #" + jsonObject.get("error_code") + " " + jsonObject.get("error_message"));
        }
    }

    return jsonObject.toString();
}

This is my implementation of Upload using urlConnection.

private String uploadURLCONN(String path){

    System.setProperty("http.proxyHost", "proxy.example.com");
    System.setProperty("http.proxyPort", "8080");

    String urlString = "http://www.bitocr.com/api";
    File file = new File(path);

    // build request parameters
    StringBody apiKey = new StringBody("api_key", ContentType.MULTIPART_FORM_DATA);
    StringBody lang = new StringBody("eng", ContentType.MULTIPART_FORM_DATA);
    FileBody fileBody = new FileBody(file, ContentType.MULTIPART_FORM_DATA);

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addPart("apikey", apiKey);
    builder.addPart("lang", lang);
    builder.addPart("file", fileBody);
    HttpEntity reqEntity = builder.build();

    try {
        URL url = new URL(urlString);
        System.out.println("Not 1");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        System.out.println("Not 2");
        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        System.out.println("Not 3");
        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);

        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.addRequestProperty("Content-length", reqEntity.getContentLength() + "");
        conn.setRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue());

        DataOutputStream os = new DataOutputStream(conn.getOutputStream());
        System.out.println("Not 4");
        reqEntity.writeTo(conn.getOutputStream());
        System.out.println("Not 5");
        os.close();
        System.out.println("Not 6");
        conn.connect();
        System.out.println("Not 7");

        if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
            System.out.println("Not 8");
            return readStream(conn.getInputStream());
        }
    }catch(Exception e){
        System.out.println("multipart post error " + e + "(" + urlString + ")");
    }
    System.out.println("returning null");
    return null;
}

I am using version 4.4 of httpClient and httpMime. And version 4.4.3 of httpCore. Any help on why my picture is not going through would be greatly appreciated.

I have ensured that the path that I'm using for the image does get the correct image and Upload() is within a correctly called AsyncTask. Thanks in advance.

This is what the documentation stated as what a raw request would look like.

    POST /api HTTP/1.1
    Content-Length:17778
    Content-Type:multipart/form-data; boundary=--------------------------               -3339166599332
    Host:www.bitocr.com

    ---------------------------3339166599332
    Content-Disposition: form-data; name="file"; filename="Untitled.png"
    Content-Type: image/png

    {image data here}
    ---------------------------3339166599332
    Content-Disposition: form-data; name="apikey"

    a7412c8ac8c8d738
    ---------------------------3339166599332
    Content-Disposition: form-data; name="lang"

    eng
    ---------------------------3339166599332
  • Well you did not tell what not works. What is the response code? Is there a catch? If so you should print e.getMessage(). – greenapps Jan 12 '16 at 17:43
  • 'conn.connect();'. Remove that line. Completely wrong trying to connect again when data is already sent. – greenapps Jan 12 '16 at 17:45
  • 'but I keep getting the error that no image has been sent (and that I have to make sure the POST request I'm sending matches the documentation).'. Where do you get that error? And. who talked about matching? – greenapps Jan 12 '16 at 17:54
  • This is the output: {"error":1,"error_message":"No input file detected. Make sure POST request are sent according to the API documentation.","error_code":5} – Junebugs in July Jan 12 '16 at 18:22
  • Are you posting to php? If so please show relevant code. That http request is pretty normal so i wonder why you have problems. But why are you still using HttpEntity? Isn't that depreecatyed too? – greenapps Jan 12 '16 at 18:37
  • I am not using any php. Im using the httpEntity because I was trying to keep it in the same format as the provided code. – Junebugs in July Jan 12 '16 at 21:18
  • Your Android code is written in Java. So not in php. But i asked if the webserver script was written in php. If so then post relevant php code. The server complains isn't it? That can be php. – greenapps Jan 12 '16 at 21:37
  • I added the provided php documentation for the raw request. – Junebugs in July Jan 13 '16 at 15:06
  • It is the bottom-most code snippet. – Junebugs in July Jan 13 '16 at 15:54
  • Ok. That is the documentation. Now please post the script itself. – greenapps Jan 13 '16 at 16:00
  • I don't have access to that. I'm sorry. This is all the documentation they gave: http://www.bitocr.com/documentation.html – Junebugs in July Jan 13 '16 at 16:50
  • `This is the code provided by the API I am using.`. Provided? Did you get that from who? Didn't you program that yourself? – greenapps Jan 13 '16 at 20:33
  • Copied your old code and it does not work here, Also the new code does not work. Are you sure you posted the right old code? As when I changed `FileBody fileBody = new FileBody(file, ContentType.MULTIPART_FORM_DATA);` to `FileBody fileBody = new FileBody(file) both worked.;` (sent to my own php script). – greenapps Jan 13 '16 at 20:35
  • I didn't write my own script. This code is for an android app to upload a photo to the bitorc API. – Junebugs in July Jan 14 '16 at 14:26
  • You are not reacting on all i asked. Why not? Please give answers. Well did you try with my solution? Why aren't you reacting on my proposal? Try that change please. – greenapps Jan 14 '16 at 14:37
  • I made your change and got the same response that said no input was detected. – Junebugs in July Jan 14 '16 at 14:51

1 Answers1

0

I am afraid your problemis too specific. The best aproach is to compare your requests (HTTPClient one with Url) using some tcp sniffer, under windows that would be fiddler. Differences will show you what you are doing wrong.

You can also try converting to full Url implementation like in the answer here: Sending files using POST with HttpURLConnection. I suppose you used sample from this SO that mixes Url with HttpClient classes, there are some comments that you might find usefull, like using setFixedLengthStreamingMode.

Community
  • 1
  • 1
marcinj
  • 48,511
  • 9
  • 79
  • 100