2016-03-30 6 views
0

Ich habe begonnen, http Client Apache API zu testen. Ich brauche es, weil ich Anfragen senden und Antworten auf virustotal API erhalten möchte. Virus Gesamt API benötigt, um Parameter in der Post-Anforderung:Wie verwende ich die apache-httpClient-API, um Datei + API-Schlüssel und andere Parameter als eine einzige Anfrage zu senden?

  1. der api Schlüsselwert (einen eindeutigen Wert für jeden Benutzer)
  2. die Datei selbst, wie ich von ihrer Website zu verstehen.

Zum Beispiel:

>>> url = "https://www.virustotal.com/vtapi/v2/url/scan" 
>>> parameters = {"url": "http://www.virustotal.com", 
...    "apikey": "-- YOUR API KEY --"} 
>>> data = urllib.urlencode(parameters) 
>>> req = urllib2.Request(url, data) 

Im Moment versuche ich, die gleiche Sache in Java anstelle von Python zu tun. Hier ist ein Teil meiner Quellcode kommentiert in den Schritten führen:

CloseableHttpClient httpClient = HttpClientBuilder.create().build(); 
    //create post request 
    HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan"); 
    //http json header 
    request.addHeader("content-type", "application/json"); 

    String str = gson.toJson(param); 

    String fileName = UUID.randomUUID().toString() + ".txt"; 

    try { 
    //API key 
    StringEntity entity = new StringEntity(str); 
    Writer writer = new BufferedWriter(new FileWriter(fileName)); 
    writer.write(VirusDefinitionTest.malware()); 
    request.setEntity(entity); 
    } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 
    MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
    FileBody fileBody = new FileBody(new File(fileName)); 

    builder.addTextBody("my_file", fileName); 
    HttpEntity entity = builder.build(); 
    request.setEntity(entity); 

    HttpResponse response; 
    try { 
    response = httpClient.execute(request); 

...

Leider erhalte ich HTTP/1.1 403 Forbidden. Offensichtlich ist der Fehler irgendwo in den Entitäten, aber ich kann nicht finden, wie es geht. Jede Hilfe wäre sehr willkommen.

Antwort

1

Das Problem scheint zu sein, dass Sie zuerst explizite "content-type" Header hinzufügen, die "application/json" ist und am Ende senden Sie die Mutiparts-Entität. Sie müssen alle Parameter und die Datei zur Entität Mutiparts hinzufügen. Nun werden die Parameter nicht senden, weil sie von Muiltipart Einheit überschrieben werden:

CloseableHttpClient httpClient = HttpClientBuilder.create().build(); 
//create post request 
HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan"); 
//http json header 
request.addHeader("content-type", "application/json"); 

String str = gson.toJson(param); 

String fileName = UUID.randomUUID().toString() + ".txt"; 

try { 
//API key 
StringEntity entity = new StringEntity(str); 
Writer writer = new BufferedWriter(new FileWriter(fileName)); 
writer.write(VirusDefinitionTest.malware()); 
// --> You set parameters here !!! 
request.setEntity(entity); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
FileBody fileBody = new FileBody(new File(fileName)); 

builder.addTextBody("my_file", fileName); 
HttpEntity entity = builder.build(); 
// --> You overwrite the parameters here !!! 
request.setEntity(entity); 

HttpResponse response; 
try { 
response = httpClient.execute(request); 
2

Dieser arbeitete für mich mit Apache 4.5.2 Httpclient:

CloseableHttpClient httpclient = HttpClients.createDefault(); 
try { 
    HttpPost httppost = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan"); 

    FileBody bin = new FileBody(new File("... the file here ...")); 
    // the API key here 
    StringBody comment = new StringBody("5ec8de.....", ContentType.TEXT_PLAIN); 

    HttpEntity reqEntity = MultipartEntityBuilder.create() 
      .addPart("apikey", comment) 
      .addPart("file", bin) 
      .build(); 

    httppost.setEntity(reqEntity); 

    System.out.println("executing request " + httppost.getRequestLine()); 
    CloseableHttpResponse response = httpclient.execute(httppost); 
    try { 
     System.out.println("----------------------------------------"); 
     System.out.println(response.getStatusLine()); 
     HttpEntity resEntity = response.getEntity(); 
     if (resEntity != null) { 
      System.out.println("ToString:" + EntityUtils.toString(resEntity)); 
     } 
     EntityUtils.consume(resEntity); 
    } finally { 
     response.close(); 
    } 
} finally { 
    httpclient.close(); 
} 

Der wichtige Teil wurde die reqEntity, die haben musste zwei speziell benannte Felder, "apikey" und "file". Das Ausführen mit einem gültigen API-Schlüssel gibt mir die erwartete Antwort von API.

+0

Das alles funktioniert hervorragend für VirusTotal mit Java. Die "EntityUtils.toString (resEntity)" war das letzte Puzzleteil. – nettie