2012-12-26 18 views
9

Sto scrivendo del codice Java che utilizza Apache HttpClient versione 4.2.2 per colpire un'API di terze parti RESTful. Questa API ha metodi che utilizzano HTTP GET, POST, PUT e DELETE. È importante notare che sto usando una versione 4.x.xe non 3.x.x, perché l'API è cambiata molto da 3 a 4. Tutti gli esempi rilevanti che ho trovato sono stati per una versione 3.x.x.Come aggiungere parametri a tutti i metodi di richiesta HttpClient?

Tutte le chiamate API richiedono di fornire il api_key come parametro (regardles di quale metodo si sta utilizzando). Ciò significa che, a prescindere dal fatto che sto facendo un GET, POST o altro, ho bisogno di fornire questo api_key in modo che la chiamata autentifichi sul lato server.

// 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"; 

Così sto cercando di capire come fornire HttpClient con la api_key indipendentemente dal mio metodo di richiesta (che a sua volta dipende da quale metodo API RESTful che sto cercando di colpire). Sembra che HttpGet non abbia nemmeno il supporto la nozione di parametri e HttpPost utilizza qualcosa chiamato HttpParams; ma di nuovo questi HttpParams sembrano solo esistere nella versione 3.x.x di HttpClient.

Allora io mi chiedo: Qual è il giusto modo per attaccare v4.2.2/aggiungere il mio api_key String a tutti e quattro:

  • HttpGet
  • HttpPost
  • HttpPut
  • HttpDelete

Grazie in anticipo.

risposta

16

È possibile utilizzare URIBuilder classe per costruire l'URI della richiesta per tutti i metodi HTTP. Il builder URI fornisce setParameter metodo per impostare il parametro.

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()); 

l'uscita dovrebbe essere

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

Grazie a @rboorgapally (+1) - tuttavia credo che funzioni solo per 'HttpGet' (impostando i parametri sulla stringa di query) e non avrebbe alcun effetto per' HttpPost', 'HttpPut' o' HttpDelete'. Sebbene ognuno di questi abbia un costruttore che accetta un 'URI' come argomento, non credo che 'URIBuilder' sappia implicitamente convertire i parametri della stringa di query in, ad esempio, variabili POST di HttpPost, ecc. Quindi, anche se dovrei passare il non -HttpGet' metodi un URI con la stringa di query completa, non credo che sapranno come convertire quella stringa di query in un formato di dati che sanno come lavorare. –

+2

Hai provato a passare l'oggetto 'URI' con i parametri a' HttpPost'? Puoi verificare se imposta automaticamente i parametri dall'oggetto 'URI'? –

+0

Mi piace solo aggiungere che 'setParameter' sostituisce il valore esistente. Quindi se si vuole impostare una variabile 'List' in URI come'/search? Q = 1 & q = 2 & y = 3', quindi qui 'q' è una lista e il suo valore finale sarà 2 non [1,2]. Per evitare questo si può usare il metodo 'addParameter' di URIBuilder. Documenti: 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

Una cosa importante qui a dire esplicitamente pacchetti di Apache è necessario utilizzare, perché ci sono diversi modi per implementare una richiesta GET.

Ad esempio, è possibile utilizzare Apache Commons o HttpComponents. In questo esempio, io uso HttpComponents (org.apache.http.*)

Richiesta classe:

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 
    } 
} 

sto usando Tomcat v7.0 Server, allora la classe di cui sopra riceve un compito e lo invia a una servlet specifica il collegamento http://localhost:8080/TesteHttpRequest/TesteDoLucas.

Il mio progetto Web dinamico si chiama TesteHttpRequest e la mia servlet assiste dall'url /TesteDoLucas

classe Task:

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; 
    } 
} 

classe 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); 
     } 
    } 

I parametri della query inviati verranno visualizzati alla console.

className = 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

Per risolvere la codifica, si può guardare qui: HttpServletRequest UTF-8 Encoding

+0

Quanto è diversa la tua risposta da quella esistente? Che valore aggrega? Avresti dovuto concentrarti sull'aggiunta dei parametri alla richiesta. La classe 'Task' è irrilevante nel contesto della domanda. –

+0

Ho postato questa domanda perché ho lo stesso dubbio giorni fa e ogni domanda che ho trovato in StackOverflow ha ignorato l'intero processo di invio della richiesta. Voglio dire, la parte di aggiungere nuovi parametri era giusta, ma ho dovuto cercare in un altro argomento come completare la richiesta (e ho trovato solo nella documentazione ufficiale) e ci ho messo del tempo. Si aggrega molto nel modo in cui è possibile copiarlo e incollarlo e avere un vero esempio funzionale della richiesta fatta con i parametri, risparmiando tempo nella ricerca dei dettagli nella documentazione. La classe di attività è irrilevante, ma aiuta ad es. –

0

È inoltre possibile utilizzare questo approccio in caso yo u vuole passare alcuni parametri HTTP e inviare una richiesta di JSON:

(nota: ho aggiunto in qualche codice aggiuntivo solo in caso aiuta tutti gli altri futuri lettori e le importazioni sono da librerie client org.apache.http)

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(); 
} 
Problemi correlati