Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > пост-индийский File Upload


Автор: smolnij 15.6.2009, 20:21
Здравствуйте. Проблема такова: из С++ программы в request web - приложения приходит base64 кодированный pdf, большого размера(~150мб). Приложение работает под JBOSS и если просто читать request.getParameter("fileName") в строку, то вылетает по OutOfMemoryError. Приложение использует struts 1.3.8. Проблема состоит в том что я получаю файл из С++ программы внутрь реквеста, соответственно не могу использовать struts'овский FormFile, и т.п.
Более того, мудрые индусы присылают файл не в multipart/form-data, а в  application/x-www-form-urlencoded, так что я не могу использовать commons file upload, чтобы получить этот файл.

я пробовал перехватывать их реквест в фильтре, и оборачивать его в org.apache.struts.upload.MultipartRequestWrapper()   (повторюсь, struts 1.3.8), но проверка для commons-file upload


if (ServletFileUpload.isMultipartContent(request)) 
все равно дает false. Юзать com.oreily я тож не могу (лицензия не та).
Я смотрел в исходники метода ServletFileUpload.isMultipartContent, он определяет просто по заголовку реквеста. Может, просто сменить заголовок? или реквест от этого мультипартом не станет? smile 

И еще, я прочитал, что все входящие переменные (как обычные, так и файловые) сохраняются либо в памяти либо на жестком диске сервера в зависимости от их размера. То есть теоретически, когда JBOSS получает в реквест большой параметр (base64 белиберда), он его сохраняет где-то на диске? А как он это сохраняет (под каким именем и где)? Может можно получить доступ к этому временному файлу?
Может я сам туплю где-то...

Я прочитал десяток веток на этом форуме по поводу file upload, но ни один пример не подошел. Там почти везде multipart, либо данные забираются с формы. А у меня тело pdf УЖЕ в request (загнанное в Base64), и надо как-то его принять и записать в файл.

Подскажите пожалуйста, что можно сделать в таком случае.

Автор: smolnij 16.6.2009, 13:28
Делаю вот что:

Фильтр, фильтрует все реквесты.

Код

Map map = request.getParameterMap();
    if (!map.containsKey(InProcessRenditionConstants.ENCRYPTED_PDF_COPY_NAME)) { //проверить, тот ли это реквест
        response.setContentType (contentType);
        chain.doFilter (request, response);
    } else { //если да, то оборачиваем его во враппер
        MultipartRequestWrapper multi = 
            new MultipartRequestWrapper((HttpServletRequest) request);
        response.setContentType (contentType);
        chain.doFilter (multi, response);
    }


Далее в коде проверяю
Код

if (request instanceof MultipartRequestWrapper) {
 Возвращает false.  smile 

Автор: goodday1941 16.6.2009, 17:56
ServletRequest.java
Код

/**
     * Retrieves the body of the request as binary data using
     * a {@link ServletInputStream}.  Either this method or
     * {@link #getReader} may be called to read the body, not both.
     *
     * @return a {@link ServletInputStream} object containing
     * the body of the request
     *
     * @exception IllegalStateException if the {@link #getReader} method
     * has already been called for this request
     *
     * @exception IOException if an input or output exception occurred
     */
    public ServletInputStream getInputStream() throws IOException;



скорее всего так можно достать... в стринг инфу перегонять нет смысла так как аутОфМемори обеспечен

Автор: smolnij 17.6.2009, 16:32
Спасибо за ответ, попробовал.
Можно перегнать в двоичном виде весь реквест в файл. Но там в реквесте есть еще параметры...
Можно их как-то повынимать, потом перегнать реквест в файл, а потом обратно положить?

Автор: goodday1941 17.6.2009, 18:09
ну тут надо ковырять... 

отделить нужную инфу скорее всего можно по каким то признакам...

теоретически Вам нужно буферно "почитывать" стрим и искать начало интересующей инфы... найдя начало начать записывать это дело куда-то (в файл скорее всего).. ну и далее почитывать почитывать до конца интересующей Вас инфы (эт тоже Вы должны определить что есть концом)... ну и в результате вы получите файл который вас интересует smile

в общем хардкодинг дикий smile

Автор: smolnij 18.6.2009, 10:35
Спасибо. В принципе гугля дает варианты как удалить объект из реквеста. Думаю сначала вынуть все другие объекты из реквеста, потом прочитать все в файл, и положить все обратно (дальше по коду пригодится).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)