Formulaire Post Multipart avec google-http-java-client
-
20-12-2019 - |
Question
Il n'est pas clair dans le client Google-http-java * Docs comment vous alliez poster un formulaire avec un champ de fichier.
Par exemple, j'essaie d'imprimer un document à l'aide de l'API d'impression Google Cloud:
HttpRequestFactory httpRequestFactory = getHttpRequestFactory();
Map<String, Object> parameters = Maps.newHashMap();
parameters.put("printerId", printRequest.getPrinterId());
parameters.put("title", printRequest.getTitle());
parameters.put("contentType", printRequest.getContentType());
parameters.put("ticket", new Gson().toJson(printRequest.getOptions()));
MultipartContent content = new MultipartContent();
content.addPart(new MultipartContent.Part(new UrlEncodedContent(parameters)));
content.addPart(new MultipartContent.Part(
new FileContent(printRequest.getContentType(), printRequest.getFile())));
try {
HttpResponse response = httpRequestFactory.buildPostRequest(
SubmitUrl, content).execute();
System.out.println(IOUtils.toString(response.getContent()));
} catch (IOException e) {
String message = String.format();
System.out.println("Error submitting print job: " + e.getMessage());
}
Malheureusement, cela ne fonctionne pas.L'API renvoie l'erreur "ID d'imprimante requis pour cette demande."Ce qui me semble comme la demande n'est pas correctement formé.
Qu'est-ce que je fais mal?
* J'utilise spécifiquement le client Google-http-java car il gère un rafraîchissement automatique des jetons OAuth, etc. pour moi.S'il vous plaît ne répondez pas avec des solutions impliquant d'utiliser d'autres clients HTTP.
La solution
Il semble que j'ai mal compris la manière dont les champs de formes sont ajoutés aux messages multipartites.Le code de travail ressemble maintenant à ceci
HttpRequestFactory httpRequestFactory = getHttpRequestFactory(username);
Map<String, String> parameters = Maps.newHashMap();
parameters.put("printerid", printRequest.getPrinterId());
parameters.put("title", printRequest.getTitle());
parameters.put("contentType", printRequest.getContentType());
// Map print options into CJT structure
Map<String, Object> options = Maps.newHashMap();
options.put("version", "1.0");
options.put("print", printRequest.getOptions());
parameters.put("ticket", new Gson().toJson(options));
// Add parameters
MultipartContent content = new MultipartContent().setMediaType(
new HttpMediaType("multipart/form-data")
.setParameter("boundary", "__END_OF_PART__"));
for (String name : parameters.keySet()) {
MultipartContent.Part part = new MultipartContent.Part(
new ByteArrayContent(null, parameters.get(name).getBytes()));
part.setHeaders(new HttpHeaders().set(
"Content-Disposition", String.format("form-data; name=\"%s\"", name)));
content.addPart(part);
}
// Add file
FileContent fileContent = new FileContent(
printRequest.getContentType(), printRequest.getFile());
MultipartContent.Part part = new MultipartContent.Part(fileContent);
part.setHeaders(new HttpHeaders().set(
"Content-Disposition",
String.format("form-data; name=\"content\"; filename=\"%s\"", printRequest.getFile().getName())));
content.addPart(part);
try {
HttpResponse response = httpRequestFactory.buildPostRequest(
SubmitUrl, content).execute();
System.out.println(IOUtils.toString(response.getContent()));
} catch (IOException e) {
...
}
Les parties les plus importantes ci-dessus remplacaient le HTTPMediatype par défaut pour spécifier "Multipart / Form-Data" et ajoutent chaque champ comme sa propre pièce avec une en-tête de "disposition de contenu" pour désigner le nom du champ de formulaire.