POST с Basic Auth не работает на Android, но работает в C # - PullRequest
4 голосов
/ 04 августа 2011

У меня есть приложение, которое я разрабатываю и которое требует от меня публикации данных в стороннем API. Я боролся с аутентификацией с самого начала и продолжал откладывать все дальше и дальше, и теперь я застрял.

Я пытался использовать Authenticator, но прочитал все о том, что в некоторых версиях Android есть ошибка: Пример аутентификации

Я пробовал несколько разных вариантов, включая Apache Commons HTTP Library, но безуспешно. После всего этого я решил убедиться, что API не является проблемой. Поэтому я написал быструю WinForms программу для тестирования API, которая отлично работала с первой попытки. Итак, идея, с которой я работаю, и API, с которым я работаю, кажутся хорошими, но мне отчаянно нужны некоторые указания относительно того, почему код Java не работает.

Примеры следуют:

Код C #, который работает каждый раз:

        System.Net.ServicePointManager.Expect100Continue = false;
        // Create a request using a URL that can receive a post. 
        WebRequest request = WebRequest.Create(addWorkoutUrl);
        // Set the Method property of the request to POST.
        request.Method = "POST";
        // Create POST data and convert it to a byte array.
        string postData = "distance=4000&hours=0&minutes=20&seconds=0&tenths=0&month=08&day=01&year=2011&typeOfWorkout=standard&weightClass=H&age=28";
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        // Set the ContentType property of the WebRequest.
        request.Headers["X-API-KEY"] = apiKey;
        request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("username:password"));
        request.ContentType = "application/x-www-form-urlencoded";
        // Set the ContentLength property of the WebRequest.
        request.ContentLength = byteArray.Length;
        // Get the request stream.
        Stream dataStream = request.GetRequestStream();
        // Write the data to the request stream.
        dataStream.Write(byteArray, 0, byteArray.Length);
        // Close the Stream object.
        dataStream.Close();
        // Get the response.
        WebResponse response = request.GetResponse();
        // Display the status.
        MessageBox.Show(((HttpWebResponse)response).StatusDescription);
        // Get the stream containing content returned by the server.
        dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        string responseFromServer = reader.ReadToEnd();
        // Display the content.
        MessageBox.Show(responseFromServer);
        // Clean up the streams.
        reader.Close();
        dataStream.Close();
        response.Close();

Java-код для Android, который в настоящее время возвращает 500: Внутренняя ошибка сервера, хотя я считаю, что это моя ошибка.

    URL url;
    String data = "distance=4000&hours=0&minutes=20&seconds=0&tenths=0&month=08&day=01&year=2011&typeOfWorkout=standard&weightClass=H&age=28";
HttpURLConnection connection = null;
    //Create connection
    url = new URL(urlBasePath);
    connection = (HttpURLConnection)url.openConnection();
    connection.setConnectTimeout(10000);
    connection.setUseCaches(false);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
    connection.setRequestProperty("Accept","*/*");
    connection.setRequestProperty("X-API-KEY", apiKey);
    connection.setRequestProperty("Authorization", "Basic " +
    Base64.encode((username + ":" + password).getBytes("UTF-8"), Base64.DEFAULT));
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" + Integer.toString(data.getBytes("UTF-8").length));

    DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
    wr.write(data.getBytes("UTF-8"));
    wr.flush();
    wr.close();
    statusCode = connection.getResponseCode();
    statusReason = connection.getResponseMessage();
    //At this point, I have the 500 error...

Ответы [ 3 ]

3 голосов
/ 05 августа 2011

Я разобрался с проблемой, и, наконец, нашел решение после того, как наткнулся на основную причину, как упомянуто в комментарии выше.

Я использовал Base64.encode() в моем примере, но мне нужно было использовать Base64.encodeToString().

Разница в том, что encode() возвращает byte[], а encodeToString() возвращает string, который я ожидал.

Надеюсь, это поможет кому-то еще, кто пойман этим.

0 голосов
/ 06 февраля 2012

Я пробовал это в Java

import java.io.*;
import java.net.*;

class download{   
    public static void main(String args[]){
        try{
            String details = "API-Key=e6d871be90a689&orderInfo={\"booking\":{\"restaurantinfo\":{\"id\":\"5722\"},\"referrer\":{\"id\": \"9448476530\" },   \"bookingdetails\":{\"instructions\":\"Make the stuff spicy\",\"bookingtime\": \"2011-11-09 12:12 pm\", \"num_guests\": \"5\"}, \"customerinfo\":{\"name\":\"Ramjee Ganti\",    \"mobile\":\"9345245530\",  \"email\": \"sajid@pappilon.in\",   \"landline\":{ \"number\":\"0908998393\",\"ext\":\"456\"}}}}";

            Authenticator.setDefault(new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                  return new PasswordAuthentication("admin", "1234".toCharArray());
                }
            });

            HttpURLConnection conn = null;
            //URL url = new URL("http://api-justeat.in/ma/orders/index");
                        URL url = new URL("http://api.geanly.in/ma/order_ma/index");
            conn = (HttpURLConnection) url.openConnection();

            conn.setDoOutput(true);
            conn.setDoInput (true);

            conn.setRequestMethod("POST");
            //conn.setRequestMethod(HttpConnection.POST);
            DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
            outStream.writeBytes(details);
            outStream.flush();
            outStream.close();          

            //Get Response  
            InputStream is = conn.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuffer response = new StringBuffer(); 

            while((line = rd.readLine()) != null) {
                 System.out.println(line);
            }

            rd.close();
            System.out.println(conn.getResponseCode() + "\n\n");
        }catch(Exception e){
                    System.out.println(e);         
        }
    }
}

это может помочь.

0 голосов
/ 03 февраля 2012

Вот лучший способ сделать POST.

install-package HttpClient

Тогда:

public void DoPost()
{
    var httpClient = new HttpClient();
    var creds = string.Format("{0}:{1}", _username, _password);
    var basicAuth = string.Format("Basic {0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(creds)));
    httpClient.DefaultRequestHeaders.Add("Authorization", basicAuth);
    var post = httpClient.PostAsync(_url, 
        new FormUrlEncodedContent(new Dictionary<string, string>
            {
                { "name", "Henrik" },
                { "age", "99" }
            }));

    post.Wait();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...