Apache HTTP Components
Apache HTTP Components este un proiect open-source, dezvoltat sub licență Apache, punând la dispoziția utilizatorilor o bibliotecă Java pentru accesarea de resurse prin intermediul protocolului HTTP.
Vom folosi o versiune legacy in acest laborator. In cadrul laboratorului veti putea folosi orice alternative, precum OkHttp.
Pentru ca metodele din API-ul Apache HTTP Components să poată fi utilizate
într-o aplicație Android este necesar să se specifice catre sistemul de build,
în fișierul build.gradle
din app
:
...
android {
// pentru fisiere build.gradle.kt
useLibrary("org.apache.http.legacy")
// pentru fisiere build.gradle
useLibrary 'org.apache.http.legacy'
}
...
De asemenea, in android manifest trebuie sa punem permisiunea de network
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission
android:name="android.permission.INTERNET"/>
...
Pentru a evita blocarea thread-ului main, oricare din apelurile catre API-ul de HTTP va trebui executat pe un thread secundar. Va reamintim o varianta cu un Thread si un handler pentru comunicare.
public class MainActivity extends AppCompatActivity {
// Handler to communicate with UI thread
private Handler mainHandler = new Handler(Looper.getMainLooper());
private TextView resultTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultTextView = findViewById(R.id.resultTextView);
// Start HTTP request when a button is clicked
Button fetchButton = findViewById(R.id.fetchButton);
// When the button is pressed, make the HTTP request
fetchButton.setOnClickListener(v -> makeHttpRequest());
}
private void makeHttpRequest() {
// We create a new thread, and inside we will run the code for the HTTP API.
new Thread(() -> {
try {
// mak
mainHandler.post(() -> {
// Here we can run code on the main thread, and use variables
// defined in the activity such as restulTextView
resultTextView.setText(result);
});
} catch (Exception e) {
// Handle error on main thread
mainHandler.post(() -> {
resultTextView.setText("Error: " + e.getMessage());
});
}
}).start();
}
}
GET. Urmatorul exemplu prezinta o cere simpla de tip GET.
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://jepi.cs.pub.ro/expr/expr_get.php?operation=times&t1=9&t2=2");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String content = httpClient.execute(httpGet, responseHandler);
if (content != null) {
/* do something with the response */
Log.i(Constants.TAG, EntityUtils.toString(httpGetEntity));
}
} catch (Exception exception) {
Log.e(Constants.TAG, exception.getMessage());
if (Constants.DEBUG) {
exception.printStackTrace();
}
}
În situația în care se dorește transmiterea de parametri către serverul web, aceștia trebuie incluși în URL (în clar), fără a se depăși limita de 2048 de caractere și folosind numai caractere ASCII:
HttpGet httpGet = new HttpGet("http:*www.server.com?attribute1=value1&...&attributen=valuen");
POST. Urmatorul exemplu prezinta o cere simpla de tip POST.
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www.server.com");
/* Lista de perechi tip (atribut, valoare) care vor contine
informatiile transmise de client pe baza carora serverul
va genera continutul, de exemplu (user, eim), (parola, 123)
*/
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("attribute1", "value1"));
* ...
params.add(new BasicNameValuePair("attributen", "valuen"));
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
httpPost.setEntity(urlEncodedFormEntity);
HttpResponse httpPostResponse = httpClient.execute(httpPost);
HttpEntity httpPostEntity = httpPostResponse.getEntity();
if (httpPostEntity != null) {
* do something with the response
Log.i(Constants.TAG, EntityUtils.toString(httpPostEntity));
}
} catch (Exception exception) {
Log.e(Constants.TAG, exception.getMessage());
if (Constants.DEBUG) {
exception.printStackTrace();
}
}
Prelucrarea raspunsurilor. Prelucrarea unui răspuns HTTP se poate realiza:
- prin prelucrarea obiectului de tip
HttpEntity,
utilizând fluxuri de intrare/ieșire:
BufferedReader bufferedReader = null; StringBuilder result = new StringBuilder(); try { * ... bufferedReader = new BufferedReader(new InputStreamReader(httpEntity.getContent())); int currentLineNumber = 0; String currentLineContent; while ((currentLineContent = bufferedReader.readLine()) != null) { currentLineNumber++; result.append(currentLineNumber).append(": ").append(currentLineContent).append("\n"); } Log.i(Constants.TAG, result.toString()); } catch (Exception exception) { Log.e(Constants.TAG, exception.getMessage()); if (Constants.DEBUG) { exception.printStackTrace(); } } finally { if(bufferedReader != null) { try { bufferedReader.close(); } catch (IOException ioException) { Log.e(Constants.TAG, exception.getMessage()); if (Constants.DEBUG) { ioException.printStackTrace(); } } } }
- utilizând un obiect de tip
ResponseHandler
, ce furnizează conținutul resursei solicitate, transmis ca parametru al metodeiexecute()
a claseiHttpClient
(pe lângă obiectulHttpGet|HttpPost
)