Изменение 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.