ByteArrayOutputStream загружен на сервер - PullRequest
0 голосов
/ 21 декабря 2009

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

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

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?

EDIT / UPDATE:

Мое решение состояло в том, чтобы сделать взаимный пост 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, но не я!

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

Ответы [ 2 ]

3 голосов
/ 21 декабря 2009

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

0 голосов
/ 21 декабря 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();
 }

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

...