2012-12-26 12 views
9

Piszę kod Java, który używa Apache HttpClient wersja 4.2.2, aby trafić RESTful 3rd party API. Ten interfejs API ma metody, które wykorzystują HTTP GET, POST, PUT i DELETE. Ważne jest, aby pamiętać, że używam wersji 4.x.x, a nie 3.x.x, ponieważ interfejs API bardzo się zmienił od 3 do 4. Wszystkie istotne przykłady znalazłem w wersji 3.x.x.Jak dodać parametry do wszystkich metod żądań HttpClient?

Wszystkie wywołania interfejsu API wymagają podania api_key jako parametru z parametrem (niezależnie od używanej metody). Oznacza to, że niezależnie od tego, czy robię GET, POST czy w inny sposób, muszę podać to api_key, aby wywołanie mogło uwierzytelnić stronę serwera.

// Have to figure out a way to get this into my HttpClient call, 
// regardless of whether I'm using: HttpGet, HttpPost, HttpPut 
// or HttpDelete... 
String api_key = "blah-whatever-my-unique-api-key"; 

Więc próbuję dowiedzieć się, jak zapewnić HttpClient z api_key niezależnie od mojej metody żądania (która z kolei zależy od których relaksującego metoda API Próbuję trafić). Wygląda na to, że HttpGet nawet nie obsługuje pojęcia parametrów, a HttpPost używa czegoś o nazwie HttpParams; ale znowu te HttpParams wydają się istnieć tylko w wersji 3.x.x HttpClient.

Więc pytam: Jaka jest właściwa, v4.2.2 sposób dołączyć/dodać mój api_key String na wszystkie cztery:

  • HttpGet
  • HttpPost
  • HttpPut
  • HttpDelete

Z góry dziękuję.

Odpowiedz

16

Można użyć URIBuilder klasę zbudować URI żądania dla wszystkich metod HTTP. Konstruktor URI zapewnia setParameter metodę ustawienia parametru.

URIBuilder builder = new URIBuilder(); 
builder.setScheme("http").setHost("www.google.com").setPath("/search") 
    .setParameter("q", "httpclient") 
    .setParameter("btnG", "Google Search") 
    .setParameter("aq", "f") 
    .setParameter("oq", ""); 
URI uri = builder.build(); 
HttpGet httpget = new HttpGet(uri); 
System.out.println(httpget.getURI()); 

Wyjście powinno być

http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq= 
+4

Dzięki @rboorgapally (+1) - jednak uważam, że działa to tylko dla 'HttpGet' (ustawiając parametry w łańcuchu zapytania) i nie ma żadnego wpływu na' HttpPost', 'HttpPut' lub' HttpDelete'. Mimo że każdy z nich ma konstruktor, który akceptuje "URI" jako argument, nie wierzę, że 'URIBuilder' niejawnie wie, aby przekonwertować parametry ciągu zapytania na, powiedzmy,' POST'owe 'HttpPost', itd. Więc myślę, że będę przechodził Non-'HttpGet' metody URI z pełnym ciągiem kwerendy, nie wierzę, że będą wiedzieć, jak przekonwertować ten ciąg zapytania do formatu danych, z którymi wiedzą, jak pracować. –

+2

Czy próbowałeś przekazać obiekt 'URI' z parametrami do' HttpPost'? Czy możesz sprawdzić, czy automatycznie ustawia parametry z obiektu 'URI'? –

+0

Po prostu dodam, że 'setParameter' nadpisuje istniejącą wartość. Więc jeśli chcemy ustawić zmienną 'List' w URI, jak'/search? Q = 1 & q = 2 & y = 3', to tutaj 'q' jest listą, a jej końcową wartością będzie 2, a nie [1,2]. Aby tego uniknąć, można użyć metody 'addParameter' w URIBuilderze. Dokumenty: http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/utils/URIBuilder.html#addParameter%28java.lang.String,%20java.lang.String % 29 –

0

Ważną rzeczą jest to, aby powiedzieć explictly pakietów Apache musi użyć, ponieważ istnieją różne sposoby do realizacji żądania GET. Na przykład można użyć Apache Commons lub HttpComponents. W tym przykładzie użyję HttpComponents (org.apache.http.*)

Zapytanie Klasa:

package request; 

import java.io.IOException; 
import java.net.URI; 
import java.net.URISyntaxException; 

import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.utils.URIBuilder; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClients; 

import Task; 

public void sendRequest(Task task) throws URISyntaxException { 

    URIBuilder uriBuilder = new URIBuilder(); 
    uriBuilder.setScheme("http") 
      .setHost("localhost") 
      .setPort(8080) 
      .setPath("/TesteHttpRequest/TesteDoLucas") 
      .addParameter("className", task.getClassName()) 
      .addParameter("dateExecutionBegin", task.getDateExecutionBegin()) 
      .addParameter("dateExecutionEnd", task.getDateExecutionEnd()) 
      .addParameter("lastDateExecution", task.getDateLastExecution()) 
      .addParameter("numberExecutions", Integer.toString(task.getNumberExecutions())) 
      .addParameter("idTask", Integer.toString(task.getIdTask())) 
      .addParameter("numberExecutions" , Integer.toString(task.getNumberExecutions())); 
    URI uri = uriBuilder.build(); 

    HttpGet getMethod = new HttpGet(uri); 

    CloseableHttpClient httpclient = HttpClients.createDefault(); 

    CloseableHttpResponse response = null; 

    try { 
     response = httpclient.execute(getMethod); 
    } catch (IOException e) { 
     //handle this IOException properly in the future 
    } catch (Exception e) { 
     //handle this IOException properly in the future 
    } 
} 

Używam Tomcat 7.0 Server, następnie klasa powyżej otrzymuje zadanie i wysyła go do określonego w servlet łącze http://localhost:8080/TesteHttpRequest/TesteDoLucas.

Moja Dynamiczny projekt WWW o nazwie TesteHttpRequest i mój aplet uczęszcza przez URL /TesteDoLucas

klasa Zadanie:

package bean; 

public class Task { 

    private int idTask; 
    private String taskDescription; 
    private String dateExecutionBegin; 
    private String dateExecutionEnd; 
    private String dateLastExecution; 
    private int numberExecutions; 
    private String className; 

    public int getIdTask() { 
     return idTask; 
    } 

    public void setIdTask(int idTask) { 
     this.idTask = idTask; 
    } 

    public String getTaskDescription() { 
     return taskDescription; 
    } 

    public void setTaskDescription(String taskDescription) { 
     this.taskDescription = taskDescription; 
    } 

    public String getDateExecutionBegin() { 
     return dateExecutionBegin; 
    } 

    public void setDateExecutionBegin(String dateExecutionBegin) { 
     this.dateExecutionBegin = dateExecutionBegin; 
    } 

    public String getDateExecutionEnd() { 
     return dateExecutionEnd; 
    } 

    public void setDateExecutionEnd(String dateExecutionEnd) { 
     this.dateExecutionEnd = dateExecutionEnd; 
    } 

    public String getDateLastExecution() { 
     return dateLastExecution; 
    } 

    public void setDateLastExecution(String dateLastExecution) { 
     this.dateLastExecution = dateLastExecution; 
    } 

    public int getNumberExecutions() { 
     return numberExecutions; 
    } 

    public void setNumberExecutions(int numberExecutions) { 
     this.numberExecutions = numberExecutions; 
    } 

    public String getClassName() { 
     return className; 
    } 

    public void setClassName(String className) { 
     this.className = className; 
    } 
} 

klasy Servlet:

package servlet; 

import java.io.IOException; 
import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

@WebServlet("/TesteDoLucas") 
public class TesteHttpRequestServlet extends HttpServlet { 
    private static final long serialVersionUID = 1L; 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     String query = request.getQueryString(); 
     System.out.println(query); 
    } 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     doGet(request, response); 
     } 
    } 

Wysłane parametry zapytania zostaną wyświetlone na konsoli.

nazwaKlasy = java.util.Objects% 3B & dateExecutionBegin = 2.016% 2F04% 2F07 + 22% 3A22% 3A22 & dateExecutionEnd = 2.016% 2F04% 2F07 + 06% 3A06% 3A06 & lastDateExecution = 2.016% 2F04% 2F07 + 11% 3A11% 3A11 & numberExecutions = 10 & idTask = 1 & numberExecutions = 10

Aby ustalić kodowanie, można spojrzeć tutaj: HttpServletRequest UTF-8 Encoding

+0

Jak różna jest twoja odpowiedź od obecnej? Jaką wartość gromadzi? Powinieneś był skupić się na dodawaniu parametrów do żądania. Klasa 'Task' nie ma znaczenia w kontekście pytania. –

+0

Wysłałem to pytanie, ponieważ mam tem wątpliwości co kilka dni temu i każde pytanie, na które znalazłem odpowiedź w stackoverflow zignorowało cały proces wysyłania zapytania. Chodzi o to, że część dodawania nowych parametrów była właściwa, ale musiałem szukać w innych tematach, jak uzupełnić wniosek (i znalazłem tylko w oficjalnej dokumentacji) i zajęło mi to trochę czasu. Gromadzi on wiele w sposób, w jaki można go kopiować i wklejać oraz mieć rzeczywisty przykład działania złożonego przy użyciu parametrów, co pozwala zaoszczędzić czas wyszukiwania szczegółów w dokumentacji. Klasa zadań jest nieistotna, ale pomaga np. –

0

można również użyć tej metody w przypadku yo u chcą przekazać pewne parametry http i wysłać żądanie json:

(uwaga: dodałem w jakimś dodatkowym kodem tylko okrywać pomaga innych przyszłych czytelników i przywóz z org.apache.http bibliotek klienckich)

public void postJsonWithHttpParams() throws URISyntaxException, UnsupportedEncodingException, IOException { 

    //add the http parameters you wish to pass 
    List<NameValuePair> postParameters = new ArrayList<>(); 
    postParameters.add(new BasicNameValuePair("param1", "param1_value")); 
    postParameters.add(new BasicNameValuePair("param2", "param2_value")); 

    //Build the server URI together with the parameters you wish to pass 
    URIBuilder uriBuilder = new URIBuilder("http://google.ug"); 
    uriBuilder.addParameters(postParameters); 

    HttpPost postRequest = new HttpPost(uriBuilder.build()); 
    postRequest.setHeader("Content-Type", "application/json"); 

    //this is your JSON string you are sending as a request 
    String yourJsonString = "{\"str1\":\"a value\",\"str2\":\"another value\"} "; 

    //pass the json string request in the entity 
    HttpEntity entity = new ByteArrayEntity(yourJsonString.getBytes("UTF-8")); 
    postRequest.setEntity(entity); 

    //create a socketfactory in order to use an http connection manager 
    PlainConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory(); 
    Registry<ConnectionSocketFactory> connSocketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() 
      .register("http", plainSocketFactory) 
      .build(); 

    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(connSocketFactoryRegistry); 

    connManager.setMaxTotal(20); 
    connManager.setDefaultMaxPerRoute(20); 

    RequestConfig defaultRequestConfig = RequestConfig.custom() 
      .setSocketTimeout(HttpClientPool.connTimeout) 
      .setConnectTimeout(HttpClientPool.connTimeout) 
      .setConnectionRequestTimeout(HttpClientPool.readTimeout) 
      .build(); 

    // Build the http client. 
    CloseableHttpClient httpclient = HttpClients.custom() 
      .setConnectionManager(connManager) 
      .setDefaultRequestConfig(defaultRequestConfig) 
      .build(); 

    CloseableHttpResponse response = httpclient.execute(postRequest); 

    //Read the response 
    String responseString = ""; 

    int statusCode = response.getStatusLine().getStatusCode(); 
    String message = response.getStatusLine().getReasonPhrase(); 

    HttpEntity responseHttpEntity = response.getEntity(); 

    InputStream content = responseHttpEntity.getContent(); 

    BufferedReader buffer = new BufferedReader(new InputStreamReader(content)); 
    String line; 

    while ((line = buffer.readLine()) != null) { 
     responseString += line; 
    } 

    //release all resources held by the responseHttpEntity 
    EntityUtils.consume(responseHttpEntity); 

    //close the stream 
    response.close(); 

    // Close the connection manager. 
    connManager.close(); 
}