Привет %username%, заголовок получился странным я в курсе но ничего не поделаешь, хочу поделиться с опытом отправки запросов и чтение ответов + БОНУС немного о обработке JSON (ох как! =) )
Для начала расскажу что мы хотим сделать к примеру авторизацию на сайте, супер пупер веб разработчик сделал для вас API и теперь вам нужно отправлять туда POST запрос с username и password, и в ответ обрабатывать JSON объект, но у вас нет опыта =)
Скажу сразу не русский я человек и за грамматические ошибки нужно сразу ругать в лс я поправлю!
Документация по Авторизации
Передаваемые поля:
POST email
POST password
При верной комбинации:
{
"message":{
"code":1,
"title":"Вы были удачно авторизованы",
"userid":/*ID юзера*/
}
}
При ошибке:
{"error":{"code":/*код ошибки*/,"message":"/*сообщение ошибки*/"}}
Понимание AsyncTask
Итак теперь нужно создать HttpClient для отправки и получения данных и HttpPost для отправки некоторых данных совсем забыл все это мы будем колотить в AsyncTask так как с интернетом НЕЛЬЗЯ пользоваться в UI потоке, создадим его, для тех кто не знаком это отдельный поток
public class Login extends AsyncTask<String, Void, String>{
/* Создаем класс AsynTask где первое значение это входные данные при старте нашего потока
второе значение это то что мы будем паблишить во время выполнения операции в потоке (пример паблишить загрузку в кб сколько осталось и тому подобное), вооот и третье значение то что мы будем получать после того как поток будет удачно выполнен
У меня входные данные текст, паблишные ничего, и ответ тоже текст */
public Login(){} //Пустой конструктор
@Override
protected void onPreExecute() {
super.onPreExecute();
} /* этот метод выполняется перед тем как начать выполнение код в отдельном потоке тут вы можете начать показывать прогресс бар */
}
@Override
protected String doInBackground(String... params) { return null; } /* то что будет выполняться в отдельном потоке String... это пугает но не бойтесь это классная фича позже поясню */
@Override
protected void onProgressUpdate(Void... values) { /* Паблишер который я описывал выше тут вы можете паблишить пользователю что хотите он выполняется в UI потоке */
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String user) { /*Наш поток завершился пришел ответ из doInBackground*/
super.onPostExecute(user);
}
Теперь в doInBackground есть такая фича как String,,, это что то типа не определенное количество входных данных т.е вы можете инициализировать его одним переменным, нескольким или массивом по желанию и настроение но когда вы в методе обращаетесь к нему он это массив :D думаю вы поняли что я хотел пояснить.
Формируем запрос
эта часть кодинга будет в методе doInBackground все описание будет в комментариях!
@Override
protected String doInBackground(String... params) {
String status = null;
DefaultHttpClient client = new DefaultHttpClient(); //HTTP клиент для отправки и получения данных
HttpPost post = new HttpPost(КУДА_БУДЕМ_ОТПРАВЛЯТЬ_НАСЯЛЬНИКА); // Создаем POST запос
List<BasicNameValuePair> pair = new ArrayList<BasicNameValuePair>(); // создаем список посылаемых данных
pair.add(new BasicNameValuePair("username", params[0]));
pair.add(new BasicNameValuePair("password", params[1]));
try {
post.setEntity(new UrlEncodedFormEntity(pair)); // теперь в наш POST метод добавляем список посылаемых данных
HttpResponse response = client.execute(post); // Отправляем запрос и записываем данные в клаасс HttpResponse
InputStream stream = response.getEntity().getContent(); // Получаем поток где храниться ответ запроса
BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); // Читаем поток и записываем в буфер
String line = null; // Здесь будет храниться строка из буффера
// т.е мы будем проходиться по каждой строке
StringBuilder builder = new StringBuilder(); // Класс для создания одного текста из множества строк
//Пока мы можем читать в буфере строку с данными будем ее читать и создавать один текст!
while ((line = reader.readLine()) != null){
builder.append(line); // Добавляем новую строку в конец текста
}
Значит в builder'e храниться текст с ответом а это JSON ответ теперь из этого текста JSON создадим класс JSON что бы им управлять!
JSONObject obj= new JSONObject(builder.toString());
Итак у нас есть JSONObject где храниться наш JSON ответ и теперь мы можем читать брать информацию и т.п
if (obj.has("message")){ // Проверяем на наличие в нашем JSON Объекта message
status = "Чувак ты авторизовался! Молодец! ';
// Как и обещал бонус показываю как распарсить верхний JSON
JSONObject message = obj.getJSONObject("message"); // Достаем из верхнего объекта, объект message <s хардкор детка</s>
String example - message.getString("title"); // Возвратит title из объекта message
}else if (obj.has("error")) {Проверяем на наличие в нашем JSON Объекта error
status = "Жалко я не умею материться :D! Нука вспоминая логин/пароль! ';
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return status;
}
После нашей эры выполненной задачи в потоке
Помните метод который вызывается после обработки данных в потоке, да сейчас настало его время
@Override
protected void onPostExecute(String status) {
super.onPostExecute(user);
Toast.makeText(ВАШ_АКТИВИТИ, status, Toast.LENGTH_SHORT).show();
}
Теперь как же теперь это все использовать? Все просто
new Login().execute("example_username", "example_userpassword");
В заключении
По идее это был урок моим друзьям, но так как я добрый малый решил поделиться данным туториалом со всеми! Любви и мира вам Хабровчане!
Спасибо за внимание!
Автор: 03uk