загрузка двух файлов в одном запросе POST на сервер rails - PullRequest
0 голосов
/ 17 марта 2011

У меня есть гибкое приложение, которое хочет загрузить два изображения на сервер rails в одном запросе POST. Я думаю, что я создаю часть данных запроса POST, но я не уверен. Когда я печатаю параметры, поступившие со стороны рельсов, я вижу только один файл.

public class MultipartDataHandler extends EventDispatcher
{
    //<net:URLLoader id="loader" complete="completeHandler(event)" dataFormat="binary"  />
    private var loaderContext:LoaderContext = new LoaderContext(true);
    private var loader:URLLoader = new URLLoader();

    public function MultipartDataHandler()
    {
    }

    public function sendToServer(exteriorBitmapData:BitmapData, interiorBitmapData:BitmapData):void {
        var xml_file:String = UserPreference.getInstance().toXML().toXMLString(); 
        var gongos_id:int = UserPreference.getInstance().gongosId;
        var room_id:int = UserPreference.getInstance().roomId;
        var car_id:int = UserPreference.getInstance().theCar.id;

        // 1. Encode image as a png

        //          var bitmap:Bitmap = image.content as Bitmap;
        //          var bytes:ByteArray = pngEncoder.encode(bitmap.bitmapData);

        var pngEncoder:PNGEncoder = new PNGEncoder();
        var exteriorBytes:ByteArray = pngEncoder.encode(exteriorBitmapData);
        var interiorBytes:ByteArray = pngEncoder.encode(interiorBitmapData);

        // 2. Create multip part request
        var boundary:String = '------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7';
        var url:String = UserPreference.urlize("/cars/upload.xml");
        var request: URLRequest = new URLRequest(url);
        request.data = getMultiPartRequestData(boundary, 'car', exteriorBytes, interiorBytes, xml_file, gongos_id, room_id, car_id);
        request.method = URLRequestMethod.POST;
        request.contentType = "multipart/form-data; boundary=" + boundary; 

        // 3. Send to Server
        loader.load(request);
        loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
        loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);

    }

    private function getMultiPartRequestData(boundary:String, resourceName:String, 
                                             exteriorBytes:ByteArray, 
                                             interiorBytes:ByteArray,
                                             xml_file:String, 
                                             gongos_id:int, room_id:int, car_id:int):ByteArray {
        var lf:String = "\r\n";
        var part1:String =  '--' + boundary + lf + 
            'Content-Disposition: form-data; name="Filename"' + lf + lf +
            '{0}' + lf +
            '--' + boundary + lf +
            'Content-Disposition: form-data; name="{1}[xml]"' + lf + lf +  
            '{2}' + lf + 
            '--' + boundary + lf + 
            'Content-Disposition: form-data; name="gongos_id"' + lf + lf +  
            '{3}' + lf + 
            '--' + boundary + lf + 
            'Content-Disposition: form-data; name="room_id"' + lf + lf +  
            '{4}' + lf + 
            '--' + boundary + lf + 
            'Content-Disposition: form-data; name="car_id"' + lf + lf +  
            '{5}' + lf + 
            '--' + boundary + lf + 
            'Content-Disposition: form-data; name="{1}[photo]"; ' +
            'filename="{0}"' + lf +
            'Content-Type: application/octet-stream' + lf +lf;
        var part2:String = '--' + boundary + lf + 
            'Content-Disposition: form-data; name="{1}[interior_photo]"; ' +
            'filename="{0}"' + lf +
            'Content-Type: application/octet-stream' + lf +lf;
        var part3:String =  '--' + boundary + lf +
            'Content-Disposition: form-data; name="Upload"' + lf + lf +
            'Submit Query' + lf +
            '--' + boundary +  '--';

        part1 = StringUtil.substitute(part1, 'car.png', resourceName, 
            xml_file, gongos_id, room_id, car_id);
        part2 = StringUtil.substitute(part2, 'interior.png', resourceName);


        var result:ByteArray = new ByteArray();
        result.writeMultiByte(part1, "ascii");
        result.writeBytes(exteriorBytes, 0, exteriorBytes.length)
        result.writeMultiByte(part2, "ascii");
        result.writeBytes(interiorBytes, 0, interiorBytes.length)
        result.writeMultiByte(part3, "ascii");

        trace(part1 + "EXTERIOR BYTES" + part2 + "INTERIOR BYTES" + part3);
        return result;
    }

}

}

Это то, что печатает консоль отладки. Обратите внимание, что я не печатаю фактические байты в консоли, так как это было бы очень больно, но вы можете видеть, куда они идут.

--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Filename"

car.png
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car[xml]"

<creation>
  <car>
    <bodyId>1</bodyId>
    <themeId>0</themeId>
    <roomId>0</roomId>
    <userId>0</userId>
    <name>null</name>
    <exterior/>
    <interior/>
  </car>
</creation>
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="gongos_id"

0
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="room_id"

1
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car_id"

0
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car[photo]"; filename="car.png"
Content-Type: application/octet-stream

EXTERIOR BYTES--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car[interior_photo]"; filename="interior.png"
Content-Type: application/octet-stream

INTERIOR BYTES--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Upload"

Submit Query
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7--

И, наконец, вот что говорит Rails.

--- !map:HashWithIndifferentAccess 
room_id: "1"
Filename: car.png
format: xml
action: upload
car_id: "0"
controller: cars
car: !map:HashWithIndifferentAccess 
  photo: !ruby/object:File {}

  xml: |-
    <creation>
      <car>
        <bodyId>1</bodyId>
        <themeId>0</themeId>
        <roomId>0</roomId>
        <userId>0</userId>
        <name>null</name>
        <exterior/>
        <interior/>
      </car>
    </creation>
gongos_id: "0"
Processing CarsController#upload to xml (for 127.0.0.1 at 2011-03-17 08:05:00) [POST]
  Parameters: {"Filename"=>"car.png", "room_id"=>"1", "car_id"=>"0", "car"=>{"photo"=>#<File:/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/RackMultipart20110317-24400-14hcvab-0>, "xml"=>"<creation>\n  <car>\n    <bodyId>1</bodyId>\n    <themeId>0</themeId>\n    <roomId>0</roomId>\n    <userId>0</userId>\n    <name>null</name>\n    <exterior/>\n    <interior/>\n  </car>\n</creation>"}, "gongos_id"=>"0"}
[paperclip] identify '-format' '%wx%h' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' 2>/dev/null
[paperclip] convert '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' '-resize' '500x500>' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0,24400,0' 2>/dev/null
[paperclip] identify '-format' '%wx%h' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' 2>/dev/null
[paperclip] convert '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' '-resize' '250x250>' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0,24400,1' 2>/dev/null
  User Load (0.3ms)   SELECT * FROM "users" WHERE ("users"."gongos_id" = '0' AND "users"."room_id" = '1') LIMIT 1
  Car Create (81.1ms)   INSERT INTO "cars" ("name", "interior_photo_file_name", "room_id", "photo_file_size", "interior_photo_file_size", "interior_photo_updated_at", "created_at", "xml", "photo_file_name", "updated_at", "body_id", "photo_content_type", "deleted", "user_id", "interior_view_id", "theme_id", "photo_updated_at", "parent_car_id", "interior_photo_content_type") VALUES('Faxo', NULL, NULL, 102547, NULL, NULL, '2011-03-17 12:05:03', '<creation>
 <car>
 <bodyId>1</bodyId>
 <themeId>0</themeId>
 <roomId>0</roomId>
 <userId>0</userId>
 <name>null</name>
 <exterior/>
 <interior/>
 </car>
</creation>', 'car.png', '2011-03-17 12:05:03', 1, 'application/octet-stream', NULL, NULL, NULL, 0, '2011-03-17 12:05:01', NULL, NULL)
[paperclip] Saving attachments.
[paperclip] saving /Users/glurban/code/amfdreamcar/public/system/photos/18/medium/car.png
[paperclip] saving /Users/glurban/code/amfdreamcar/public/system/photos/18/original/car.png
[paperclip] saving /Users/glurban/code/amfdreamcar/public/system/photos/18/thumb/car.png
[paperclip] Saving attachments.
Rendering cars/upload
Completed in 2750ms (View: 60, DB: 81) | 200 OK [http://localhost/cars/upload.xml]

Итак, как видите, в параметрах появляется только одна фотография (первая). При переключении заказа появляется только interior_photo. Что я делаю не так?

Я также пытался сделать два отдельных вызова, соединенных вместе, но это не удалось из-за ограничения безопасности Flash 10, которое запрещает загрузку файлов без выполнения пользователем какого-либо действия, например нажатия кнопки. Я даже попытался поместить оба вызова на loader.load() в одной и той же функции, используя генератор случайных чисел для создания идентификатора на гибкой стороне (потому что рельсы должны знать, что эти два вызова относятся к одной и той же машине, и без объединения Я не могу использовать ответ от первого вызова для передачи идентификатора машины), но я столкнулся с состоянием гонки, когда второй вызов каким-то образом попал на сервер до первого. Безопасность Adobe ... FFFFFFFUUUUUU.

1 Ответ

0 голосов
/ 17 марта 2011

О боже.

Потратил около 3 часов на эту проблему (отладка, пробование других неудачных решений и т.

Затем, сразу после публикации, я понимаю, что проблема: разрывы строк будут смертью меня. Добавьте lf в начало part2 и part3, и мы в порядке.

: O

...