ByteArrayOutputStream загружен на сервер

Я работаю над апплетом, который взаимодействует с панелью для подписи. API панели подписи имеет функцию, которая возвращает BufferedImage (предположим, что она называется API_CALL_TO_RETURN_BUFFERED_IMAGE()). Я могу кодировать в jpeg и отлично записывать это изображение в файл (используя FileOutputStream). Однако вместо записи на локальный диск мне нужно загрузить изображение в формате jpeg на сервер. Я могу отправить данные на сервер просто отлично, и я могу просто кодировать изображение; но я борюсь за то, чтобы две задачи встретились посередине.

Ниже приведена сокращенная версия кода (try-catch, функция, классы опущены):

ByteArrayOutputStream baos = new ByteArrayOutputStream();
JPEGImageEncode jie = JPEGCodec.createJPEGEncoder(baos);
jpeg.encode(API_CALL_TO_RETURN_BUFFERED_IMAGE());         // assume magic

// baos now contains jpeg data

URLConnection urlc = new URL(some_url).openConnection();
// set up urlc request headers and such
DataOutputStream dos = new DataOutputStream(urlc.getOutputStream());
dos.writeBytes(???);   // ??? should be image=[the data in baos above]

// close stuff

Изначально я думал:

String post_data = URLEncoder.encode("image=" + new String(baos.toByteArray()), some_charset);
dos.writeBytes(post_data);

Но это явно искажает изображение.

Вот как выглядит правильное (написанное локально) изображение

Я могу разместить только одну гиперссылку, но искаженное изображение здесь: imgur.com/mbmJL.jpg

Как мне записать ByteArrayOutputStream в DataOutputStream?

РЕДАКТИРОВАТЬ/ОБНОВИТЬ:

Мое решение состояло в том, чтобы сделать mutlipart POST. Причиной установки заголовка Content-Type как multipart/form-data была, как эта ссылка, http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4, говорит:

multipart/form-data следует использовать для файлов, значений, отличных от ascii, или двоичных данных.

Что касается записи ByteArrayOutputStream в DataOutputStream, это выглядит так:

dos.writeBytes(baos.toByteArray());

Я уверен, что это тривиально для штатных Java-программистов, но не для меня!

Я не использовал предложенную библиотеку, потому что она предлагала гораздо больше, чем мне было нужно.


person Community    schedule 21.12.2009    source источник


Ответы (2)


Я бы упростил некоторые из вышеперечисленных действий, используя HttpClient для управления публикацией. Вот руководство по Post и (если нужно) Учебное пособие по многостраничной публикации. Непонятно, что вам нужно, но использование HttpClient решит множество проблем при создании структуры и содержимого HTTP-запроса.

person Brian Agnew    schedule 21.12.2009
comment
HttpClient очень удобен и прост в использовании, это правда) - person Roman; 21.12.2009
comment
Знаешь, изначально я думал, что проблема в моей java (я ее много не пишу), но теперь я думаю, что проблема в декодировании данных изображения на сервере. - person ; 21.12.2009

Когда вы записываете один поток в другой, это может привести к большим накладным расходам; буферы, блоки try/catch, .close(), дополнительные блоки try/catch.

Библиотека ввода-вывода Apache Commons автоматизирует большую часть этого за вас.

Если вы никуда не торопитесь, придумайте, как это сделать, но в долгосрочной перспективе просто используйте Commons IO. В качестве примера того, как работает буферизованная копия, первый пример со страницы ввода-вывода Commons показывает первую половину; вместо System.out.println вы хотите записать строку в другой поток.

 InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
 try {
   InputStreamReader inR = new InputStreamReader( in );
   BufferedReader buf = new BufferedReader( inR );
   String line;
   while ( ( line = buf.readLine() ) != null ) {
     System.out.println( line );
   }
 } finally {
   in.close();
 }

Если ваш файл не является строковыми данными, вы захотите прочитать byte[] вместо String.

person Dean J    schedule 21.12.2009