【问题标题】:Android Http Post to REST ApiAndroid Http 发布到 REST Api
【发布时间】:2013-08-06 06:17:36
【问题描述】:

您好,我主要是一名 Android 开发人员,对 http 协议一无所知,非常感谢您的帮助!

我正在尝试对此进行 api 调用:http://api.haikutest.com/developer/apidoc/assignments.html 我在设备上发布文件。

他们提供了以下示例请求:

POST /api/assignments/3/submit
message[subject]=Subject+of+the+message&message[body]=Some+long+text&message[sent_at]=2013-07-05&message[draft]=0&message[assignment_id]=3&files[][file]=%23%3CFile%3A0x007ff59c9c1de8%3E&files[][filename]=test.pdf

并且在描述状态下文件参数是:

文件数组,每个元素包含文件名的哈希值和 base64编码文件

这是我现在正在尝试的代码(注意:我正在使用 Robospice + Spring for Android):

   File file = new File(Environment.getExternalStorageDirectory() +
                "/DCIM/Camera/1357279228432.jpg");
        Base64InputStream stream = new Base64InputStream(new FileInputStream(file), 0);
        HttpHeaders headers = new HttpHeaders();
        headers.add("x-haiku-auth", HaikuAPI.getAuthHeader());
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
        parts.add("files[][file]", parts);
        HttpEntity<Object> request = new HttpEntity<Object>(stream, headers);
        UriComponentsBuilder builder = UriComponentsBuilder
                .fromUriString(
                        "https://" + HaikuAPI.getDomain() + "/api/assignments")
                .pathSegment(assignmentID + "", "submit")
                .queryParam("message[subject]", "Assignment Completed")

                .queryParam("message[body]", message)
                .queryParam("message[assignment_id]", assignmentID)
                .queryParam("files[][filename]", "test.jpg");

        URI url = builder.build().toUri();

        String response = getRestTemplate().postForObject(url, request, String.class);
        return response;

但我收到一条错误消息,指出它无法将流序列化为 JSON。按照 API 文档,我是否必须将流作为参数?还有什么是实现这个的正确方法?如果我不必对用户设置文件大小限制,我会很高兴,因此流。虽然我已经让它处理以 Base64 编码并直接作为参数放置的小文件......

非常感谢任何帮助!对于小指针,我绝对不会对 cme​​ts 或答案投反对票。

更新

更新了代码,但仍然收到另一条错误消息:

00:25:50.904 Thread-2066 An exception occurred during request network execution :Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [application/x-www-form-urlencoded]

【问题讨论】:

  • 我不太确定,但我怀疑如果服务希望您简单地发送 1 个完整请求,您是否可以流式传输文件
  • @stefan 示例请求中包含 word 文件,对于 PDF 来说非常短......他们是怎么做到的?

标签: android http rest post android-internet


【解决方案1】:

看起来您正在使用Spring for Android。判断错误消息似乎 Spring 强制内容类型为application/json,而我相信您正在尝试发送application/x-www-form-urlencoded。所以设置这个Content-Type 标头:

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

Spring 会知道匹配正确的MessageConverter。有关此here 的更多信息。

编辑:另外,您应该在 POST 数据中发送请求数据,而不是在请求 URI 中。将其移至MultiValuesMap。看看我给你的链接如何发布这些数据。有关这些的完整文档也可以在 here 找到。

EDIT2 您还需要为您的回复设置MessageConverter。比如:

List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
headers.setAccept(acceptableMediaTypes);

EDIT3如果您需要发送文件,请考虑使用Resource,更具体的是InputStreamResource。但是有一个技巧:你需要提供文件名和文件大小,否则你的请求会崩溃。比如:

Resource res = new InputStreamResource(context.getContentResolver().openInputStream(itemImage)) {
                @Override
                public String getFilename() throws IllegalStateException {
                    return fileInfo.getFileName();
                }

                @Override
                public long contentLength() throws IOException {
                    return fileInfo.getFileSizeInBytes();
                }
            };

【讨论】:

  • 谢谢我回家试试
  • 我试过了,但没用...我更新了我的问题以反映这一点。我做错了什么?
  • 只需为您发送的内容找到相应的 MessageConverter 即可。你可以试试headers.setContentType(MediaType.TEXT_PLAIN);吗?
  • ... 然后需要设置对应的MessageConverter进行响应。为此编辑了我的答案。
  • 问题/解决方案是什么?
猜你喜欢
  • 2016-05-30
  • 2014-03-26
  • 2015-04-27
  • 2023-04-04
  • 2013-10-30
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多