简体   繁体   English

使用google-http-java-client发布多部分表单

[英]Post multipart form with google-http-java-client

It's not clear from the google-http-java-client* docs how you would go about posting a form that has a file field. 从google-http-java-client * docs中不清楚如何发布一个包含文件字段的表单。

For example I'm trying to print a document using the Google Cloud Print API: 例如,我正在尝试使用Google Cloud Print API打印文档:

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

Unfortunately this doesn't work. 不幸的是,这不起作用。 The API returns the error "Printer Id required for this request." API返回错误“此请求所需的打印机ID”。 which seems to me like the request isn't properly formed. 在我看来,请求没有正确形成。

What am I doing wrong? 我究竟做错了什么?

* I'm specifically using the google-http-java-client as it handles automatic refreshing of OAuth tokens etc for me. *我专门使用google-http-java-client,因为它可以为我自动刷新OAuth令牌等。 Please don't reply with solutions that involve using other HTTP clients. 请不要回复涉及使用其他HTTP客户端的解决方案。

So it looks like I misunderstood how form fields are added to multipart messages. 所以看起来我误解了如何将表单字段添加到多部分消息中。 The working code now looks like this 工作代码现在看起来像这样

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) {
    ...
}

The most important parts above were overriding the default HttpMediaType to specify "multipart/form-data" and adding each field as its own part with a "Content-Disposition" header to designate the form field name. 上面最重要的部分是覆盖默认的HttpMediaType以指定“multipart / form-data”,并将每个字段添加为自己的部分,并使用“Content-Disposition”标头指定表单字段名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM