2015-08-17 63 views
2

我目前正在尝试处理用户上传的服务器上的图像。我的目标是拍摄上传的图像,在服务器上处理它,然后将其上传到rackspace云文件。我找到一条路没有运气。我希望有人能带领我走向正确的方向。在飞镖中处理图像

继承人是我迄今为止在服务器端进行处理

Future <Null> handleUploadRequest(final HttpRequest httpRequest) async { 
    print('handle upload -------------------------'); 

    var data; 

    await httpRequest.fold(new BytesBuilder(), (b, d) => b..add(d)).then((builder) { 
    data = builder.takeBytes(); 

    String encodedData = JSON.encode(data); 

    int dataLength = encodedData.length; 

    // Uploading image to rackspace cloud files 

    // Here we have to send a request with username & api key to get an auth token 
http.post(tokens, headers : {'Content-Type':'application/json'}, body: JSON.encode({"auth": {"RAX-KSKEY:apiKeyCredentials":{"username":"XXXXXXXXXXXXXXX","apiKey":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}}})).then((response) { 
    print("Response status: ${response.statusCode}"); 
    print("Response body: ${response.body}"); 
    return response; 
}).then((response){ 
    authResponse = JSON.decode(response.body); 
    String token = authResponse['access']['token']['id']; 


/////////// This is where we upload the image to Rackspace /////// 

    var request = new http.MultipartRequest("PUT", Uri.parse('https://storage101.iad3.clouddrive.com/v1/MossoCloudFS_XXXXXXX/TestContainer/testimage.jpg')); 
    request.headers['X-Auth-Token'] = token; 
    request.headers['Content-Type'] = 'image/jpeg'; 

    var stream = new http.ByteStream.fromBytes(data); 

    request.files.add(new http.MultipartFile('file', stream, data.length, filename: 'testfile.jpg', contentType: 'image/jpeg'); 
    print('requesT: ${request}'); 
    request.send().then((response) { 
    print(response.statusCode); 
    print(response.headers); 
    print(response.stream); 
    if (response.statusCode == 200) print("Uploaded!"); 
    }); 


//// End of Upload to Rackspace ////////// 

    print('Upload Complete!'); 
    httpRequest.response.write(data); 
    await httpRequest.response.close(); 
} 

唯一的问题现在的问题是,在https://pub.dartlang.org/packages/http,我需要调用的参数内容类型类型的MediaType。我不知道如何调用它。它好像是一个班级内的工厂?如果我不调用内容类型,那么它默认为不能从cdn存储容器打开的八位字节流。

参考上传的这个方法是从How can I upload a PDF using Dart's HttpClient?

+1

做我的建议会导致不同的行为呢?你可以编辑你的问题,并直接在你的问题中添加错误输出。 [dart]和[dart-async]标签下方有一个编辑链接。 –

+0

在http.put(..)之前放置一个返回将不会让它运行。它打印它读取和进入的字节。然后((_)。 –

+1

我在我的答案中添加了一个纯粹的'async' /'await'实现,我认为它更容易推理。如果它更好/更差/相同? –

回答

1

看起来像一个丢失returnhttp.put(...)之前和httpRequest.response.close();

无论您使用await每个异步调用之前(调用它会返回一个未来的功能),或返回各这样的Future给调用者保存执行顺序。如果没有这些异步执行计划在稍后执行,并且代码的下一行将在您调用的异步代码甚至开始之前执行。

更新纯异步/等待执行

import 'package:http/http.dart' as http; 
import 'dart:async' show Future, Stream; 
import 'dart:io'; 

Future<Null> handleUploadRequest(final HttpRequest httpRequest) async { 
    print('handle upload -------------------------'); 
    print('httpRequest: ${httpRequest.headers}'); 

    var data; 

    var builder = await httpRequest.fold(new BytesBuilder(), (b, d) => b..add(d)); 
    data = builder.takeBytes(); 
    print('bytes builder: ${data}'); 

    // Uploading image to rackspace cloud files 
    var url = 
     'https://storage101.dfw1.clouddrive.com/v1/{accountnumber}/{container}/'; 
    var response = await http.put(url, 
     headers: { 
     'X-Auth-Token': '{XXXXXXXXXAPI_KEYXXXXXXXXXX}', 
     'Content-Type': 'image/jpeg', 
     'Content-Length': '${httpRequest.headers.contentLength}', 
     }, 
     body: data); 

    print("Response status: ${response.statusCode}"); 
    print("Response body: ${response.body}"); 

    print('closing connection with data complete'); 
    httpRequest.response.write(data); 
    await httpRequest.response.close(); 
} 
+0

我得到'SocketException:写入失败,地址= storage101.dfw1.clouddrive.com,端口= 62429'当更新时,这比我之前所做的更好(哪一个是未处理的例外)。谢谢你:)。现在我需要弄清楚为什么我会遇到SocketException问题。 –

+1

我自己并没有使用过cloudfiles,但看着我发现的一些文档,除了帐户和容器之外,您可能还需要添加一个对象名称。 –

+0

当我上次使用php的服务时,他们有一个简单的sdk,我只需要导入,这就是为什么这对我来说是不同的。爱Dart虽然 –