Изменение DynamicChannelBuffer в Netty на String и обратно на ChannelBuffer

Мой веб-сервер написан на Scala с использованием библиотеки Finagle в Twitter, которая, в свою очередь, использует Netty. Таким образом, содержимое запроса возвращается как DynamicChannelBuffer. Если я загружаю изображение на сервер, используя curl из терминала, как это:

 curl -T "abc.jpg" http://127.0.0.1:8080/test/image

Затем я могу прочитать и переслать изображение на внутренний веб-сервер, используя пакет SOAP, который выглядит следующим образом:

      <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Header>
          <AuthHeader xmlns="http://www.testtesttest.co.za/">
            <LogonID>testtesttest</LogonID>
            <Password>testtesttest</Password>
          </AuthHeader>
        </soap:Header>
        <soap:Body>
          <uploadFile xmlns="http://www.testtesttest.co.za/">
            <FileDetails>
               <FileName>image.jpg</FileName>
              <FileContents>
                 {(Base64.encode(request.getContent())).toString(UTF_8)
              </FileContents>
            </FileDetails>
          </uploadFile>
        </soap:Body>
      </soap:Envelope>

В приведенном выше примере код: (Base64.encode(request.getContent())).toString(UTF_8) преобразует содержимое запроса в строку с кодировкой base 64.

Проблема в том, что мне нужно прочитать содержимое изображения из запроса Multipart Http, отправленного из мобильного приложения PhoneGap. PhoneGap не дает мне никакой возможности, отправлять только изображение, и настаивает на загрузке файла в качестве составного запроса.

Чтобы разбить составной запрос на части, я изменяю результат request.getContent() на строку, используя toString(UTF_8), а затем получаю часть данных изображения, разделяя многосоставное сообщение http на отдельные части:

 var requestParts = request.content.toString(UTF_8).split("\\Q--*****org.apache.cordova.formBoundary\\E")
 val imageParts = requestParts(3).split("\\n\\s*\\n")
 val imageHeader = imageParts(0)
 val imageBody = imageParts(1)

Это дерьмо, я знаю (я поправлюсь позже), но пока делает свое дело. imageBody теперь имеет содержимое изображения в виде строки.

Теперь, если я верну imageBody обратно в пакет SOAP, мне придется снова его кодировать, используя:

 val encoder = new BASE64Encoder();
 val encodedImage = encoder.encode(imageBody)

На данный момент изображение просто искажено. Его размер выглядит правильно, но я что-то напутал с преобразованием строк или кодированием. В первом примере я использую кодировщик Netty, но во втором примере я использую стандартный кодировщик Java. Причина в том, что кодер Netty может кодировать только объекты типа ChannelBuffer.

Я не хочу говорить это слишком громко, но я боролся с этим больше суток. Любая помощь здесь будет с благодарностью.

1 ответ

Решение

Так что это работает:

image --> [curl] ------> post1 -->  [your code] --> soap msg 1 --> [back-end]

Это не:

image --> [phonegap] --> post2 -->  [your code] --> soap msg 2 --> [back-end]

Чтобы надежно решить проблему такого типа, вам необходимо понять, какая кодировка используется на каждом этапе.

Предполагая, что вы можете использовать одно и то же изображение, можете ли вы проверить необработанное закодированное содержимое в post1 и post2 и определить, какая кодировка используется? Затем, когда вы поймете это, запишите содержимое в своем коде, когда вы декодируете, и перекодируйте сообщение. Таким образом, вы можете убедиться, что это одинаково для мыла msg1 и мыла msg2.

Другие вопросы по тегам