简体   繁体   English

Android Http Post到REST Api

[英]Android Http Post to REST Api

Hi I'm primarily an Android developer and am pretty clueless about http protocols, you help would be much appreciated! 嗨,我主要是一名Android开发人员,对http协议一无所知,您的帮助将不胜感激!

I am trying to make an api call to this: http://api.haikutest.com/developer/apidoc/assignments.html where I POST a file on the device. 我试图对此进行api调用: http : //api.haikutest.com/developer/apidoc/assignments.html我在设备上张贴文件的位置。

They give a sample request of: 他们提供了以下示例请求:

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

And in the description state that the files param is: 在描述状态下,文件参数为:

Array of files with each element containing a hash of filename and base64 encoded file 文件数组,每个元素包含文件名和base64编码文件的哈希

This is the code that I'm trying right now (note: I'm using Robospice + Spring for Android): 这是我现在正在尝试的代码(注意:我正在使用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;

But I get an error saying that it can't serialize the stream to JSON. 但是我收到一条错误消息,说它无法将流序列化为JSON。 Following the API documentation do I have to place the stream as a param? 根据API文档,我是否必须将流作为参数放置? Also what is the correct way to implement this? 另外,实现此目标的正确方法是什么? I would love if I didn't have to put a file size limit on the user, hence the streams. 如果我不必对用户(因此流)设置文件大小限制,我将非常喜欢。 Though I have gotten it to work with small files encoded in Base64 and placed directly as a param... 虽然我已经将其与以Base64编码并直接作为参数放置的小文件一起使用...

Any help is greatly appreciated! 任何帮助是极大的赞赏! I will definitely not downvote comments or answers for small pointers. 对于小指针,我绝对不会拒绝评论或答案。

Updated 更新

Updated code, but still get another error message: 更新了代码,但仍然收到另一条错误消息:

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]

Looks like you're using Spring for Android . 看起来您正在使用Spring for Android Judging that error message it seems Spring forces the content type to be application/json , while I believe you're trying to send application/x-www-form-urlencoded . 从该错误消息来看,Spring似乎将内容类型强制为application/json ,而我相信您正在尝试发送application/x-www-form-urlencoded So set this Content-Type header: 因此,请设置以下Content-Type标头:

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

Spring will know then to match the proper MessageConverter . 然后Spring会知道要匹配正确的MessageConverter More info on this here . 在此更多信息在这里

EDIT : Also, you're supposed to send the request data in POST data, not in request URI. 编辑 :另外,您应该以POST数据而不是请求URI的形式发送请求数据。 Move that to a MultiValuesMap . 将其移动到MultiValuesMap Have a look at the link I gave you how to post such data. 看看我给您提供的如何发布此类数据的链接。 A complete documentation on these can also be found here . 关于这些的完整文档也可以在这里找到。

EDIT2 You need to set the MessageConverter for your response as well. EDIT2您还需要为您的响应设置MessageConverter Something like: 就像是:

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

EDIT3 If you need to send files, consider using Resource , to be more specific InputStreamResource . EDIT3如果您需要发送文件,请考虑使用Resource ,以更具体地讲InputStreamResource But there is a trick: you need to provide the file name and the file size, otherwise your request will crash. 但是有一个窍门:您需要提供文件名和文件大小,否则您的请求将崩溃。 Something like: 就像是:

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

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

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