====== Laborator 07. Invocarea de Servicii Web prin Protocolul HTTP ====== De multe ori, funcționalitatea pe care o pun la dispoziție aplicațiile Android este preluată din alte surse, datorită limitărilor impuse de capacitatea de procesare și memorie disponibilă ale unui dispozitiv mobil. O strategie posibilă în acest sens este utilizarea HTTP, pentru interogarea unor servicii web. **HTTP** (Hypertext Transfer Protocol) este un protocol de comunicație responsabil cu transferul de hipertext (text structurat ce conține legături) dintre un client (de regulă, un navigator) și un server web, interacțiunea dintre acestea (prin intermediul unei conexiuni TCP persistente pe portul 80) fiind reglementată de [[http://www.rfc-editor.org/rfc/rfc2616.txt|RFC 2616]]. Principalele concepte cu care lucrează acest protocol sunt //cererea// și //răspunsul//. * **cererea** este transmisă de client către serverul web și reprezintă o solicitare pentru obținerea unor resurse (identificate printr-un URL); aceasta conține denumirea metodei care va fi utilizată pentru transferul de informații, locația de unde se găsește resursa respectivă și versiunea de protocol; * **răspunsul** este transmis de serverul web către client, ca rezultat al solicitării primite, incluzând și o linie de stare (ce conține un cod care indică dacă starea comenzii) precum și alte informații suplimentare {{ :laboratoare:laborator07:functionare_protocol_http.png?nolink&500 }} În Android, comunicația dintre un server web si un client poate fi gestionată prin intermediul clasei [[http://developer.android.com/reference/java/net/HttpURLConnection.html|HttpURLConnection]], care pune la dispoziție aceleași funcționalități ca în cazul Java SE. O aplicație ce utilizează această clasă presupune implementarea următoarelor etape: - instanțierea unui obiect [[http://developer.android.com/reference/java/net/URL.html|URL]] prin intermediul căruia pot fi obținute informații cu privire la resursa respectivă (protocolul utilizat, mașina pe care se găsește resursa respectivă, portul pe care poate fi accesată, fișierul accesat, referința vizualizată): * ''getProtocol()'' - furnizează protocolul utilizat, în acest caz, ''http''; * ''getHost()'' - indică adresa mașinii care găzduiește resursa respectivă; * ''getPort()'' - întoarce portul pe care s-a realizat comunicația: * valoarea -1 este specifică pentru situația în care nu s-a precizat un port în mod explicit; * valoarea 80 este transmisă numai în cazul în care aceata este specificată ca atare în adresa furnizată. * ''getFile()'' - specifică calea de la care este obținută resursa; * ''getRef()'' - precizează referința din cadrul paginii HTML (de regulă, de tip ancoră) care a fost solicitată. - deschiderea unei conexiuni, printr-un apel al metodei ''openConnection()''; metoda întoarce un obiect de tip ''URLConnection'' care poate fi convertit la ''HttpURLConnection'' prin care se oferă acces la: * antetele de cerere: ''setRequestMethod()'', ''setRequestProperty(String, String)''; * antetele de răspuns, inclusiv linia de stare: ''getResponseCode()'', ''getHeaderFields()'', ''getResponseMessage()''; * informații referitoare la mecanismele de gestiune a stării (cookie-uri) - în condițiile în care HTTP este un protocol fără stare; se utilizează clasele [[http://developer.android.com/reference/java/net/CookieManager.html|CookieManager]], [[http://developer.android.com/reference/java/net/CookieHandler.html|CookieHandler]], care gestionează la nivelul întregii mașini virtuale obiectele de tipul [[http://developer.android.com/reference/java/net/HttpCookie.html|HttpCookie]]. - utilizarea unui flux de intrare / flux de ieșire pentru transferul de informații; se folosesc, obiectele / metodele: * ''BufferedInputStream'' / ''getInputStream()''; * ''BufferedOutputStream'' / ''getOutputStream()'' - în acest caz, trebuie apelată metoda ''setDoOutput()'' cu parametrul ''true'', împreună cu metodele care evită reținerea conținutului într-o zonă tampon (consumând astfel memorie inutilă și având un impact asupra latenței): * ''setFixedLengthStreamingMode()'' - atunci când dimensiunea conținutului este cunoscută în prealabil; * ''setChunkedStreamingMode()'' - atunci când dimensiunea conținutului nu este cunoscută - închiderea conexiunii, prin intermediul metodei ''disconnect()''. Implicit, clasa ''HttpURLConnection'' folosește metoda ''GET''. Metoda ''POST'' este utilizată numai în situația în care a fost apelată în prealabil metoda ''setDoOutput(true)''. Celelalte metode (''OPTIONS'', ''HEAD'', ''PUT'', ''DELETE'', ''TRACE'') pot fi utilizate numai în situația în care sunt specificate explicit ca parametru al funcției ''setRequestMethod()''. Verificarea existenței unui cuvânt cheie într-o pagină Internet poate fi realizată astfel: private class WebPageKeywordSearchThread extends Thread { @Override public void run() { HttpURLConnection httpURLConnection = null; String errorMessage = null; try { String webPageAddress = webPageAddressEditText.getText().toString(); String keyword = keywordEditText.getText().toString(); if (webPageAddress == null || webPageAddress.isEmpty()) { errorMessage = "Web Page address cannot be empty"; } if (keyword == null || keyword.isEmpty()) { errorMessage = "Keyword cannot be empty"; } if (errorMessage != null) { final String finalizedErrorMessage = errorMessage; resultsTextView.post(new Runnable() { @Override public void run() { resultsTextView.setText(finalizedErrorMessage); } }); return; } URL url = new URL(webPageAddress); StringBuffer resultsTextViewContent = new StringBuffer(); resultsTextViewContent.append("Protocol: " + url.getProtocol() + "\n"); resultsTextViewContent.append("Host: " + url.getHost() + "\n"); resultsTextViewContent.append("Port: " + url.getPort() + "\n"); resultsTextViewContent.append("File: " + url.getFile() + "\n"); resultsTextViewContent.append("Reference: " + url.getRef() + "\n"); resultsTextViewContent.append("==========\n"); URLConnection urlConnection = url.openConnection(); if (urlConnection instanceof HttpURLConnection) { httpURLConnection = (HttpURLConnection)urlConnection; BufferedReader bufferedReader = Utilities.getReader(httpURLConnection); int currentLineNumber = 0, numberOfOccurrencies = 0; String currentLineContent; while ((currentLineContent = bufferedReader.readLine()) != null) { currentLineNumber++; if (currentLineContent.contains(keyword)) { resultsTextViewContent.append("line: "+currentLineNumber+" / "+currentLineContent+"\n"); numberOfOccurrencies++; } } resultsTextViewContent.append("Number of occurrencies: "+numberOfOccurrencies+"\n"); final String finalizedResultsTextViewContent = resultsTextViewContent.toString(); resultsTextView.post(new Runnable() { @Override public void run() { resultsTextView.setText(finalizedResultsTextViewContent); } }); } } catch (MalformedURLException malformedURLException) { Log.e(Constants.TAG, malformedURLException.getMessage()); if (Constants.DEBUG) { malformedURLException.printStackTrace(); } } catch (IOException ioException) { Log.e(Constants.TAG, ioException.getMessage()); if (Constants.DEBUG) { ioException.printStackTrace(); } } finally { if (httpURLConnection != null) { httpURLConnection.disconnect(); } } } } {{ :laboratoare:laborator07:webpagekeywordsearch.png?nolink&400 }} Comunicația dintre serverul web și client trebuie să se realizeze pe un fir de execuție separat, în caz contrar fiind generată excepția ''android.os.NetworkOnMainThreadException''. În fișierul ''AndroidManifest.xml'' trebuie specificată permisiunea de acces la rețea:\\ ''''. O practică curentă este de a verifica codul de răspuns transmis de a accesa fluxul de intrare asociat resursei respective. Astfel, numai în situația în care valoarea întoarsă de metoda ''getResponseCode()'' este ''HttpURLConnection.HTTP_OK'' se poate continua procesarea conținutului stocat la URL-ul accesat. ===== Cereri HTTP ===== O cerere HTTP conține una sau mai multe linii de text ASCII, precedate în mod necesar de denumirea metodei specificând operația ce se va realiza asupra conținutului respectiv: ^ **DENUMIRE METODĂ** ^ **DESCRIERE** ^ | **''GET''** | descărcarea resursei specificate de pe serverul web pe client; majoritatea cererilor către un server web sunt de acest tip\\ GET /page.html HTTP/1.1 Host: www.server.com | | ''HEAD'' | obținerea antetului unei pagini Internet, pentru a se verifica parametrii acesteia sau doar pentru a testa corectitudinea unui URL | | ''PUT'' | încărcarea resursei specificate de pe client pe serverul web (cu suprascrierea acesteia, în cazul în care există deja); trebuie specificate și datele de autentificare, utilizatorul respectiv trebuind să aibă permisiunile necesare pentru o astfel de operașie | | **''POST''** | transferul de informații de către client cu privire la resursa specificată, acestea urmând a fi prelucrate de serverul web\\ POST /page.html HTTP/1.1 Host: www.server.com attribute1=value1&...&attributen=valuen | | ''DELETE'' | ștergerea resursei specificate de pe serverul web, rezultatul operației depinzând de permisiunile pe care le deține utilizatorul ale cărui date de autentificare au fost transmise în antete | | ''TRACE'' | solicitare de retransmitere a cererii primite de serverul web de la client, pentru a se testa corectitudinea acesteia | | ''CONNECT'' | rezervat pentru o utilizare ulterioară | | ''OPTIONS'' | interogare cu privire la atributele serverului web sau ale unei resurse găzduite de acesta | Capitalizarea este importantă atunci când se precizează denumirea metodei folosite, făcându-se distincție între minuscule și majuscule. O linie de cerere HTTP poate fi succedată de unele informații suplimentare, reprezentând **antetele de cerere**, acestea având forma ''atribut:valoare'', fiind definite următoarele proprietăți: * ''User-Agent'' - informații cu privire la browser-ul utilizat și la platforma pe care rulează acesta * informații cu privire la conținutul pe care clientul îl dorește de la serverul web, având capacitatea de a-l procesa; dacă serverul poate alege dintre mai multe resurse pe care le găzduiește, va alege pe cele care respectă constrângerile specificate, altfel întoarce un cod de eroare * ''Accept'' - tipul MIME * ''Accept-Charset'' - setul de caractere * ''Accept-Encoding'' - mecanismul de codificare * ''Accept-Language'' - limba * ''Host'' (obligatoriu) - denumirea gazdei pe care se găsește resursa (specificată în URL); necesară întrucât o adresă IP poate fi asociată mai multor nume de DNS * ''Authorization'' - informații de autentificare în cazul unor operații care necesită drepturi privilegiate * ''Cookie'' - transmite un cookie primit anterior * ''Date'' - data și ora la care a fost transmisă cererea În Android, conexiunile HTTP sunt gestionate mai ales prin intermediul clasei [[http://developer.android.com/reference/org/apache/http/client/HttpClient.html|HttpClient]], care oferă suport complet pentru acest protocol de comunicație. Acesta este o implementare [[http://hc.apache.org/httpcomponents-client-4.4.x/index.html|Apache Http Components]] care este integrată în SDK, fără a se specifica însă versiunea utilizată. Cel mai frecvent, un obiect de acest tip este folosit pentru transmiterea unor cereri de tip ''GET'' ([[http://developer.android.com/reference/org/apache/http/client/methods/HttpGet.html|HttpGet]]) sau ''POST'' ([[http://developer.android.com/reference/org/apache/http/client/methods/HttpPost.html|HttpPost]]) și prelucrarea răspunsurilor corespunzătoare. ==== GET vs. POST ==== Deși atât metoda ''GET'' cât și metoda ''POST'' pot fi utilizate pentru descărcarea conținutului unei pagini Internet, transmițând către serverul web valorile unor anumite atribute, între acestea există anumite diferențe: * o cerere ''GET'' poate fi reținută în cache, fapt ce nu este valabil și pentru o cerere ''POST''; * o cerere ''GET'' rămâne în istoricul aplicației de navigare, fapt ce nu este valabil și pentru o cerere ''POST''; * o cerere ''GET'' poate fi reținută printre paginile Internet favorite din cadrul programului de navigare, fapt ce nu este valabil și pentru o cerere ''POST''; * o cerere ''GET'' impune unele restricții cu privire la lungimea (maxim 2048 caractere) și la tipul de date (doar caractere ASCII) transmise (prin URL), fapt ce nu este valabil și pentru o cerere ''POST''; * o cerere ''GET'' nu trebuie folosită atunci când sunt implicate informații critice (acestea fiind vizibile în URL), fapt ce nu este valabil și pentru o cerere ''POST''; * o cerere ''GET'' ar trebui să fie folosită doar pentru obținerea unei resurse, fapt ce nu este valabil și pentru o cerere ''POST''. ==== Cereri de tip GET ==== Metoda ''GET'' este folosită pentru obținerea conținutului unei pagini Internet stocată la o anumită adresă. Pașii care trebuie urmați pentru realizarea unei astfel de cereri HTTP sunt: - instanțierea unui obiect de tipul ''HttpClient''; - instanțierea unui obiect de tipul ''HttpGet'' având ca parametru adresa serverului web ce conține resursa care se dorește a fi descărcată; - realizarea propriu-zisă a cererii HTTP prin apelul metodei ''execute()'' a obiectului ''HttpClient'', ce primește ca parametru obiectul de tip ''HttpGet'' (încapsulând tipul metodei folosite și locația care va fi interogată). === Exemplu utilizare GET === try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://www.server.com"); HttpResponse httpGetResponse = httpClient.execute(httpGet); HttpEntity httpGetEntity = httpGetResponse.getEntity(); if (httpGetEntity != 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(); } } ==== ==== Alternativ, poate fi utilizat un obiect de tip [[http://developer.android.com/reference/org/apache/http/client/ResponseHandler.html|ResponseHandler]] care va fi transmis ca parametru metodei ''execute()'', astfel încât rezultatul acesteia să fie un șir de caractere conținând resursa care se dorește a fi descărcată. // ... ResponseHandler responseHandler = new BasicResponseHandler(); String content = httpClient.execute(httpGet, responseHandler); // ... În situația în care se dorește transmiterea de parametri către serverul web, aceștia trebuie incluși în URL, 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"); // ... ==== Cereri de tip POST ==== Metoda ''POST'' este folosită atunci când se dorește generarea unui conținut de către serverul web pe baza unor informații transmise de client. Aceste date - având forma unei liste de tip (atribut, valoare) - vor fi incluse în conținutul mesajului în loc de a fi integrate în cadrul URL-ului. Pașii care trebuie urmați pentru realizarea unei astfel de cereri HTTP sunt: - instanțierea unui obiect de tipul ''HttpClient''; - instanțierea unui obiect de tipul ''HttpPost'' având ca parametru adresa serverului web ce conține resursa care se dorește a fi descărcată; - **definirea unei liste de perechi de tip (atribut, valoare) (de tip ''List'') care vor conține informațiile transmise de client pe baza cărora serverul web va genera conținutul**; - **atașarea datelor respective la obiectul de tip ''HttpPost'' (apelând metoda ''setEntity()'') prin intermediul unei entități ''UrlEncodedFormEntity'' care primește ca parametru informațiile ce trebuie transmise și mecanismul de codificare a datelor**; - realizarea propriu-zisă a cererii HTTP prin apelul metodei ''execute()'' a obiectului ''HttpClient'', ce primește ca parametru obiectul de tip ''HttpPost'' (încapsulând tipul metodei folosite, datele care se doresc a fi transmise și locația care va fi interogată). === Exemplu utilizare POST === try { HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost("http://www.server.com"); List params = new ArrayList(); 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(); } } ===== Răspunsuri HTTP ===== Un răspuns HTTP este format din linia de stare, antetele de răspuns și posibile informații suplimentare, conținând o parte sau toată resursa care a fost solicitată de client de pe serverul web. În cadrul **liniei de stare** este inclus un cod din trei cifre care indică dacă solicitarea a putut fi îndeplinită sau nu (situație în care este indicată și cauza). ^ **FAMILIE DE CODURI** ^ **SEMNIFICAȚIE** ^ **DESCRIERE** ^ | 1xx | Informație | răspuns provizoriu, constând din linia de stare și alte antete (fără conținut, terminat de o linie vidă), indicând faptul că cererea a fost primită, procesarea sa fiind încă în desfășurare; nu este utilizată în HTTP/1.0 | | 2xx | Succes | răspuns ce indică faptul că cererea a fost primită, înțeleasă, acceptată și procesată cu succes | | 3xx | Redirectare | răspuns transmis de serverul web ce indică faptul că trebuie realizate acțiuni suplimentare din partea clientului (cu sau fără interacțiunea utilizatorului, în funcție de metoda folosită) pentru ca cererea să poată fi îndeplinită; în cazul în care redirectarea se repetă de mai multe ori, se poate suspecta o buclă infinită | | 4xx | Eroare la client | răspuns transmis de serverul web ce indică faptul că cererea nu a putut fi îndeplinită, datorită unei erori la nivelul clientului; mesajul include și o entitate ce conține o descriere a situației, inclusiv tipul acesteia (permanentă sau temporară) | | 5xx | Eroare la server | cod de răspuns ce indică clientului faptul că cererea nu a putut fi îndeplinită, datorită unei erori la nivelul serverului web; mesajul include și o entitate ce conține o descriere a situației, inclusiv tipul acesteia (permanentă sau temporară) | Mesajul conține și **antetele de răspuns**, având forma ''atribut:valoare'', fiind definite următoarele proprietăți: * ''Server'' - informații cu privire la mașina care găzduiește resursa care este transmisă * informații cu privire la proprietățile conținutului care este transmis * ''Content-Encoding'' - mecanismul de codificare * ''Content-Language'' - limba * ''Content-Length'' - dimensiunea * ''Content-Type'' - tipul MIME * ''Last-Modified'' - ora și data la care pagina Internet a fost modificată * ''Location'' - informație prin care serverul web informează clientul de faptul că ar trebui folosit alt URL (resursa a fost mutată sau trebuie accesată o pagină Internet localizată în funcție de anumite preferințe) * ''Accept-Ranges'' - informație referitoare la transmiterea conținutului solicitat în mai multe părți, corespunzătoare unor intervale de octeți * ''Set-Cookie'' - transmiterea unui cookie de la serverul web la client, acesta trebuind să fie inclus în antetele ulterioare ale mesajelor schimbate între cele două entități În Android, prelucrarea unui răspuns HTTP se poate realiza: * prin prelucrarea obiectului de tip ''HttpEntity'', utilizând fluxuri de intrare/ieșire:\\ BufferedReader bufferedReader; 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 + ": " + currentLineContent + "\n"); } bufferedReader.close(); 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 metodei ''execute()'' a clasei ''HttpClient'' (pe lângă obiectul ''HttpGet|HttpPost'') ===== Prelucrare DOM (Document Object Model) ===== Documentele HTML au o structură arborescentă, având drept rădăcină un document al cărui copil este o ierarhie de elemente, fiecare dintre acestea fiind reprezentate de o etichetă. {{ :laboratoare:laborator07:ierarhie_document_html.png?nolink&900 }} Fiecare element poate conține mai multe atribute (fiecare dintre acestea având o valoare asociată), putând încorpora și o valoare. '' valoare '' Nu este însă obligatoriu ca elementul să conțină nici atribute și nici valoare, putând avea și o structură care nu le include: '''' O soluție pentru parsarea unui document HTML este reprezentată de biblioteca [[http://jsoup.org/packages/jsoup-1.8.2.jar|Jsoup]]. Biblioteca ''jsoup-1.8.2.jar'' trebuie plasată în directorul ''libs'' al proiectului Android și adăugată la calea pentru compilare (//Build Path// → //Add to Build Path...//). Prin intermediul metodei statice [[http://jsoup.org/apidocs/org/jsoup/Jsoup.html#parse(java.lang.String)|parse()]] ce primește ca parametru conținutul resursei care se dorește a fi analizată (codul sursă al paginii HTML), se obține un obiect [[http://jsoup.org/apidocs/org/jsoup/nodes/Document.html|Document]], care permite parcurgerea ierarhiei de elemente. Pentru un obiect de tipul ''org.jsoup.nodes.Document'', pot fi obținute secțiunile componente '''' și '''' prin intermediul metodelor [[http://jsoup.org/apidocs/org/jsoup/nodes/Document.html#head()|head()]], respectiv [[http://jsoup.org/apidocs/org/jsoup/nodes/Document.html#body()|body()]]. Fiecare etichetă din codul sursă corespunzător unei pagini HTML este reprezentat de un obiect [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html|Element]], prin intermediul căruia pot fi accesate toate atributele și valorile asociate acestora. Inclusiv nodul rădăcină (de tip ''org.jsoup.nodes.Document'') este derivat din ''org.jsoup.nodes.Element''. Pentru un element, pot fi realizate următoarele operații: * obținerea (listei) unor elemente componente: * deținând un anumit identificator - [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementById(java.lang.String)|getElementById(String id)]]; * care au o anumită etichetă - [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByTag(java.lang.String)|getElementsByTag(String tag)]]; * ce fac parte din cadrul unei clase - [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByClass(java.lang.String)|getElementsByClass(String className)]]; * în funcție de o proprietate: * pentru care se precizează atributul * [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttribute(java.lang.String)|getElementsByAttribute(String key)]]; * [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttributeStarting(java.lang.String)|getElementsByAttributeStarting(String keyPrefix)]]; * pentru care se precizează valoarea * [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttributeValueStarting(java.lang.String, java.lang.String)|getElementsByAttributeValueStarting(String key, String valuePrefix)]] * [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttributeValueContaining(java.lang.String, java.lang.String)|getElementsByAttributeValueContaining(String key, String match)]] * [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttributeValueEnding(java.lang.String, java.lang.String)|getElementsByAttributeValueEnding(String key, String valueSuffix)]] * [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttributeValueMatching(java.lang.String, java.util.regex.Pattern)|getElementsByAttributeValueMatching(String key, Pattern pattern)]] * [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttributeValueMatching(java.lang.String, java.lang.String)|getElementsByAttributeValueMatching(String key, String regex)]]; * pentru care se precizează atât atributul cât și valoarea - [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#getElementsByAttributeValue(java.lang.String, java.lang.String)|getElementsByAttributeValue(String key, String value)]]. * navigare în cadrul ierarhiei de elemente: * obținerea elementului părinte: [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#parent()|parent()]]; în situația în care se dorește obținerea tuturor elementelor părinte (până la rădăcină), se poate folosi metoda [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#parents()|parents()]]; * obținerea elementelor copii: [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#children()|children()]], [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#child(int)|child(int index)]] - numerotarea făcându-se în acest caz începând cu 0. * obținerea elementelor de pe același nivel: [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#siblingElements()|siblingElements()]], [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#firstElementSibling()|firstElementSibling()]], [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#lastElementSibling()|lastElementSibling()]], [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#nextElementSibling()|nextElementSibling()]], [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#previousElementSibling()|previousElementSibling()]]; * investigarea unor informații cu privire la proprietăți: * identificatorul - [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#id()|id()]]; * eticheta - [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#tag()|tag()]], [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#tagName()|tagName()]]; * clasa / clasele - [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#className()|className()]] / [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#classNames()|classNames()]]; * atribut: * lista tuturor atributelor - [[http://jsoup.org/apidocs/org/jsoup/nodes/TextNode.html#attributes()|attributes()]]; * valoarea asociată unui anumit atribut - [[http://jsoup.org/apidocs/org/jsoup/select/Elements.html#attr(java.lang.String)|attribute(String attributeKey)]]; * textul conținut, din care sunt eliminate caracterele albe, acesta fiind totodată normalizat: [[http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#text()|text()]]; * datele, pentru etichetele ''