POST с Basic Auth не работает на Android, но работает в C #

У меня есть приложение, которое я разрабатываю, и мне нужно отправлять данные в сторонний 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... 

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

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

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

Надеюсь, это поможет кому-то другому, кто поймал это.

Вот более удобный способ сделать 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(); } 

Я пробовал это в 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); } } } 

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

Intereting Posts
Что лучше с точки зрения производительности синтаксического анализа в Android, XML или JSON? Настроить диалоговое окно быстрого действия для Android Как подключиться к кнопке Power в Android? : CheckDebugManifest FAILED => файл, указанный для свойства 'manifest', не существует Невозможно получить входящие запросы в facebook Что произойдет, если служба облачных данных Parse завершится с ошибкой? Различать нажатие кнопки «home» и открытие другого действия Как передать форматированную строку даты из моего DatePickerFragment? Как отключить подписку на Facebook для Android – Facebook-android-sdk Правильно определить тип устройства Android Замена фрагментов не работает / Я выполняю это правильно? OnItemClickListener не запускает пользовательский ArrayAdapter Как узнать, почему файл «R» (ресурс) не сгенерирован? Вызов PublinSubject onNext в другом потоке после обновления до Retrofit 2.0 Стандартная формальный стиль