Heroku未处理来自Android的多部分表单帖子

Heroku未处理来自Android的多部分表单帖子,android,heroku,Android,Heroku,我在Rails4上有一个API,它以文件上传的形式接受HTTP请求。在Localhost上一切正常,但在Heroku上,POST请求似乎没有任何作用 这就是我的Android POST请求的样子: public static byte[] postData(String operation, byte[] binaryData) { String urlString = baseUrl + "/" + operation; String boundary = "uahbkjqtjgecu

我在Rails4上有一个API,它以文件上传的形式接受HTTP请求。在Localhost上一切正常,但在Heroku上,POST请求似乎没有任何作用

这就是我的Android POST请求的样子:

public static byte[] postData(String operation, byte[] binaryData) {
String urlString = baseUrl + "/" + operation;
    String boundary = "uahbkjqtjgecuaoehuaebkjahj";

    byte[] postData = null;
    URLConnection urlConnection;
    DataInputStream responseDataInputStream;

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    StringBuffer startBuffer = new StringBuffer("--").append(boundary).append("\r\n");
    startBuffer.append("Content-Disposition: form-data; name=\"data\"; ").append("filename=\"data.dat\"\r\n");
    startBuffer.append("Content-Type: application/octet-stream\r\n\r\n");
    StringBuffer endBuffer = new StringBuffer("\r\n--").append(boundary).append("--\r\n");

    String startRequestData = startBuffer.toString();
    String endRequestData = endBuffer.toString();
    try {
        URL url = new URL(urlString);
        urlConnection = url.openConnection();
        urlConnection.setDoInput(true);
        urlConnection.setDoOutput(true);
        urlConnection.setUseCaches(false);

        urlConnection.setConnectTimeout(5000); //5 seconds
        urlConnection.setReadTimeout(5000);//5 seconds

        urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        urlConnection.connect();
        DataOutputStream _request = new DataOutputStream(urlConnection.getOutputStream());

        // Write the start portion of the request
        byteArrayOutputStream.write(startRequestData.getBytes());
        postData = byteArrayOutputStream.toByteArray();
        _request.write(postData);

        // Write the Binary Packet
        _request.write(binaryData);

        // Write the end portion of the request
        byteArrayOutputStream.reset();
        byteArrayOutputStream.write(endRequestData.getBytes());
        postData = byteArrayOutputStream.toByteArray();
        _request.write(postData);

        _request.flush();
        _request.close();

        // Read in the response bytes
        InputStream is = urlConnection.getInputStream();
        responseDataInputStream = new DataInputStream(is);
        byteArrayOutputStream.reset();
        byte[] buffer = new byte[responseDataInputStream.available()];

        while (responseDataInputStream.read(buffer) != -1) {
            byteArrayOutputStream.write(buffer);
            buffer = new byte[responseDataInputStream.available()];
        }

        byte[] responseData = byteArrayOutputStream.toByteArray();

        return responseData;

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (SocketTimeoutException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new byte[0];
}

我的rails控制器

skip_before_filter  :verify_authenticity_token
respond_to :raw
before_filter :read_file

def read_file
 data = params[:data].tempfile
 data_compressed = ''
 File.open(data, 'r') do |file|
   file.each do |line|
    data_compressed.concat(line)
   end
 end

 @json_data = Zlib::Inflate.inflate(data_compressed)
end

def an_action
 #processing stuff
 response = Zlib::Deflate.deflate(j_response)
 send_data @json_response.to_s
end
Heroku日志显示控制器操作已命中,但日志中没有其他内容

2015-05-05T22:39:29.860161+00:00 heroku[router]: at=info method=POST path="/api/login" host=[my app].herokuapp.com request_id=9d9c91b1-2ce2-4db5-9b54-3dea0322e211 fwd="197.237.24.179" dyno=web.1 connect=4ms service=12ms status=500 bytes=1683
2015-05-05T22:40:40.952219+00:00 heroku[router]: at=info method=POST path="/api/signup" host=[my app].herokuapp.com request_id=4adac44c-66e6-4001-a568-8eb913176091 fwd="197.237.24.179" dyno=web.1 connect=4ms service=8ms status=500 bytes=1683

在将我的注意力从Heroku转移到Android代码之后,我发现在代码的这一部分有一个无休止的循环:

while (responseDataInputStream.read(buffer) != -1) {
        byteArrayOutputStream.write(buffer);
        buffer = new byte[responseDataInputStream.available()];
    }
当无需读取时,返回值为0而不是-1。因此,我将其更新为:

while (responseDataInputStream.read(buffer) > 0) {
            byteArrayOutputStream.write(buffer);
            buffer = new byte[responseDataInputStream.available()];
        }
奇怪的是,在localhost上,第一段代码可以工作,而且应该也可以在生产环境中工作。文档声明,如果到达流的末尾,将返回-1。也许这是另一天的讨论,因为现在我正在使用第二段代码

编辑

这个问题困扰了我好几个星期,在谷歌搜索和调整代码之后,我想指出这种方法是错误的。该代码在WIFI连接上工作,但在3G上总是失败。因此,我将列出最终有效的代码更改

  • 使用HttpURLConnection而不是URLConnection。理由
  • 将连接和读取超时的大小分别从5000增加到30000和120000
  • 将while条件恢复为
    while(responsedainputstream.read(buffer)!=-1)