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


Автор: webmaster35 26.1.2010, 09:42
Как это реализовать ? Желательно подробнее . Я имею в виду не просто загрузить файл-картинку, толку от этого мало  , а с конкретной целью. Ну например скажем для простейшего примера возьмем новости. У них должно быть :

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

Ну а по файлу например так. Выкладывать на теоретический сайт моды, то есть также заголовок, описание , ну и сама ссылка на этот мод , по которой его можно скачать .

Автор: afon 26.1.2010, 12:51
Ищи file upload по той технологии, на которой делаешь свой application.

Не в тему: а вообще не могу понять, откуда в j2ee лезут слова типа "админка"... это ж из разряда сайтоклепателей на пхп за 100 рублей за полдня... когда я слышу слово "админка", меня начинает сипать smile 

Автор: webmaster35 26.1.2010, 16:48
Цитата(afon @ 26.1.2010,  12:51)
Ищи file upload по той технологии, на которой делаешь свой application.

Не в тему: а вообще не могу понять, откуда в j2ee лезут слова типа "админка"... это ж из разряда сайтоклепателей на пхп за 100 рублей за полдня... когда я слышу слово "админка", меня начинает сипать smile

Не нашел примеров, искал много . Разрабатывать хочу без фреймворков, так как на русском ничего нету, а с англ у меня плохо
Ну а что вместо административной панели управления сайтом должно быть ?

Автор: magicfly 26.1.2010, 18:08
админка вполне нормальная вещь. 
по вопросу: http://www.jguru.com/faq/view.jsp?EID=160

Автор: webmaster35 26.1.2010, 21:12
Цитата(magicfly @ 26.1.2010,  18:08)
админка вполне нормальная вещь. 
по вопросу: http://www.jguru.com/faq/view.jsp?EID=160

Я смотрю все рекомендуют либу FileUpload от апач. Примеры на ней есть ?

Автор: serger 27.1.2010, 08:23
Ну, например, вот:
http://www.theserverside.com/tt/articles/article.tss?l=HttpClient_FileUpload
http://www.developershome.com/wap/wapUpload/wap_upload.asp?page=jsp3
правда примеры немного не правильные.

Автор: dobrolub 27.1.2010, 09:00
в сервлет 3.0 добавлена функциональность для закачивания файлов. Имплементировано в resin 4.0.3 и должно быть в  glassfish (RI всё-таки). Нормальный блог пост по этой функциональности тут (англ. но код на java smile ):
http://blog.caucho.com/?p=237

Автор: webmaster35 27.1.2010, 11:56
Цитата(serger @ 27.1.2010,  08:23)
Ну, например, вот:
http://www.theserverside.com/tt/articles/article.tss?l=HttpClient_FileUpload
http://www.developershome.com/wap/wapUpload/wap_upload.asp?page=jsp3
правда примеры немного не правильные.

А правильные примеры в природе на этой либе ( от апача ) есть ? 
Может кто ни будь сделать пример короткий на ней, но работающий, законченный ? Я думаю не одному мне это бы пригодилось, в F.A.Q. можно будет вынести. А то так хочется сделать загрузку картинок например, галерею простую, и не знаю за что браться. Моды чтобы заливать с описаниями и т.д. на сервак . А не знаю как делать и все тут .

Автор: serger 27.1.2010, 12:38
Цитата(webmaster35 @  27.1.2010,  11:56 Найти цитируемый пост)
Может кто ни будь сделать пример короткий на ней, но работающий, законченный ? 

Может. Это ты!  smile 
В приведённых примерах нужно только логику из JSP вытащить, а так они должны работать..
Или можешь попытаться ещё поискать в могучем google, я первые пару ссылок вытащил.

Автор: Samotnik 27.1.2010, 13:09
Я делал, как раз то, что тебе нужно. Закачка картинок на сервер smile 
Использовал fileUpload от апачча. 

Автор: webmaster35 27.1.2010, 17:21
Цитата(Samotnik @ 27.1.2010,  13:09)
Я делал, как раз то, что тебе нужно. Закачка картинок на сервер smile 
Использовал fileUpload от апачча.

Может еще и кодом поделишься  smile  .
Как я понял то что я хочу это не просто загрузка файлов, а еще их хранение и главное отображения для закачек. Что вообще искать надо ?

Автор: magicfly 27.1.2010, 18:15
Возможно Вы немного не поняли весь процесс. Сохраняете изображение через например файлаплоад. У вас получается например массив байтов. Далее его где то надо сохранить. 2 варианта: база либо папка на серваке. Далее у вас уже сохранен этот файл. Если необходимо вычитать этот файл,например идет запрос вида <img src=http.../>
Соответствующий сервлет возвращает те вычитаные байты и соответствующий контент тайп например "image/gif" or "image/jpeg". 

Автор: webmaster35 27.1.2010, 19:56
Цитата(magicfly @ 27.1.2010,  18:15)
Возможно Вы немного не поняли весь процесс. Сохраняете изображение через например файлаплоад. У вас получается например массив байтов. Далее его где то надо сохранить. 2 варианта: база либо папка на серваке. Далее у вас уже сохранен этот файл. Если необходимо вычитать этот файл,например идет запрос вида <img src=http.../>
Соответствующий сервлет возвращает те вычитаные байты и соответствующий контент тайп например "image/gif" or "image/jpeg".

Примеры на все это есть ? У меня опыт никудышный, ничего подобного я еще не делал

Автор: magicfly 28.1.2010, 02:00
это можно но возникает вопрос в технологиях и другие непонятные места. 
В общем показан абстрактный процесс. Лучше Вам указывать на непонятые места что бы сразу их решать

Автор: gelo86 1.2.2010, 09:44
Цитата(magicfly @  27.1.2010,  18:15 Найти цитируемый пост)
например идет запрос вида <img src=http.../>


1. Часто мы создаем war, в котором должны быть рисунки. Если они появляются динамически, то после редеплоя (стераем старый и копируем новый war), все картинки теряются. Возможно както tomcat v5,v6 или jetty v6 настроить так, чтобы при теге <img src='path' /> рисунков искал не относительно распакованного war'а, а относительно савсем другой директории (даже хоть на другом диске) ?

2. Стоит ли сохранять дополнительно в базе данных рисунки ? Вдруг ктото стерет с диска фаилы ? Ето безопасно ?

Автор: magicfly 1.2.2010, 15:25
1. ЭЭЭ, а каким образом они появляются в этом варе? как хранятся? Вообще как вы построите отображение так оно и будет. Если <img src="http://mySite/picture.jsp"> и ваш сервер обрабатывает подобные запросы то присоединив контроллер легко возвращать их как вам будет угодно
2. С какого диска ? С сервера ? Если кто то может стереть эти файлы то у него как минимум есть доступ (логин\пароль). Другой вопрос это backup'ы, которые можно настроить и они никак не связаны с приложением. Хотя если вам щекотно в определенных местах то никто не запрещает сохранять вам в базе 

Автор: gelo86 1.2.2010, 21:20
Цитата(magicfly @  1.2.2010,  15:25 Найти цитируемый пост)
присоединив контроллер легко возвращать их


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

Автор: magicfly 4.2.2010, 15:51
а как хотелось бы? а какие это картинки?
Вдруг их базе мульйоны а вы их кешите 

Автор: iluvatar 21.3.2010, 22:36
Я подниму тему потому что у меня продолжение вопроса.
Я так понял, что картинки лучше хранить в файловой системе, а не в БД (в ней хранятся пути).
Вопроса три:
1. Я юзаю tomcat - куда он имеет доступ в ФС? Где конкретно их хранить? Можете кусочек кода для примера привести? Какие настройки есть?
2. Можно ли при загрузке как-то ограничивать размер? Посмотреть какого размера файл хочет закачать пользователь я не смогу (или таки смогу), а можно ли после загрузки файла до максимального размера рвать закачку и информировать? Наверняка же есть стандартные решения?
3. Если хранить в ФС, то как делать бекап?

Автор: MaxPayneC 22.3.2010, 00:21
Цитата(iluvatar @  21.3.2010,  22:36 Найти цитируемый пост)
Я так понял, что картинки лучше хранить в файловой системе, а не в БД (в ней хранятся пути).

Это зависит от задачи.

Цитата(iluvatar @  21.3.2010,  22:36 Найти цитируемый пост)
1. Я юзаю tomcat - куда он имеет доступ в ФС? Где конкретно их хранить?

Томкат имеет доступ в /tmp, свой темп и туда, куда вы пропишете ему доступ. Прописать права на каталог с картинками, если вы храните их в ФС - нормальная практика.

Цитата(iluvatar @  21.3.2010,  22:36 Найти цитируемый пост)
2. Можно ли при загрузке как-то ограничивать размер?

Я использовал фреймворк struts 2, там был в конфиге для этого параметр.

Цитата(iluvatar @  21.3.2010,  22:36 Найти цитируемый пост)
3. Если хранить в ФС, то как делать бекап? 

Кроном, я полагаю.

Автор: iluvatar 22.3.2010, 00:42
спасибо большое, буду пробовать

Автор: iluvatar 29.3.2010, 11:05
еще раз подниму тему. 
ни одного нормального плагина не нашел, придется дописывать самому.

Что хочется:
  есть форма в которую пользователь вводит какую-то инфу и может добавить несколько картинок (например, не более 3-х). 
  каждая картинка (или все сразу) загружаются сразу после их выбора, создается превью и показывается
  после чего пользователь в основной форме делает сабмит - и картинки идут на сервер

Как я думаю это делать:
  в основной форме будет вспомогательная спец. для картинок, ведь иначе аяксом мы не сможем ее отправить на сервер

А теперь вопросы:
  1. как передать превью после загрузки? Я же должен отдать респонс в формате xml или json.
  2. как картинка должна передаться на сервер в основной форме?
  3. где она должна храниться после загрузки вспомогательной форме, чтобы не грузить ее по 2 раза?

Спасибо за умные ответы

Автор: iluvatar 29.3.2010, 20:48
Придумал такую штуку - аяксом мы картинку грузим всерьез, она сейвится на диске, создается соотв. запись в базе. 
Назад возвращается ее id, по которому мы отображаем ее (т.е. делаем элемент с src="/getImagePreview?id=123123").
Если пользователь засабмитил основную форму, то картинке ставится флаг, что она используется (имеется в виду, столбец в БД).
Каждые скажем 12 часов запускается скрипт, который удаляет все неиспользуемые картинки.
Как вам решение? Велосипед, костыль или таки я гений?

Автор: iluvatar 31.3.2010, 20:00
Цитата(MaxPayneC @ 22.3.2010,  01:21)
Цитата(iluvatar @  21.3.2010,  22:36 Найти цитируемый пост)
1. Я юзаю tomcat - куда он имеет доступ в ФС? Где конкретно их хранить?

Томкат имеет доступ в /tmp, свой темп и туда, куда вы пропишете ему доступ. Прописать права на каталог с картинками, если вы храните их в ФС - нормальная практика.

Хммм... не могу найти как tomcat'у дать доступ на папку на диске.
Подскажите конфиг

Автор: MaxPayneC 31.3.2010, 21:17
Первый способ, небезопасный

chmod 755 images
chown images tomcat:tomcat

Второй способ, более безопасный, но работает только на ext4 с включенными ACL:

setfacl -m u:tomcat:rw images
setfact -m d:u:tomcat:rw images

Автор: iluvatar 31.3.2010, 23:30
кхм...
я полагал, что достаточно добавить что-то в context.xml, т.е. это полностью в сфере томкэта
ваш вариант для unix систем, а что делать смертным пользователям windows ?

Автор: MaxPayneC 1.4.2010, 08:50
Пользователям windows перейти на unix использовать стандартные свойства выставления привилегий - свойства-безопасность на папке, кажется.

Автор: 0x00 19.4.2010, 07:23
томкат может писать файлы куда угодно, где есть права на запись конечно.
сначала думал хранить файлы в блобах БД, потом передумал из-за ресурсоемкости, решил просто складывать файлы в папку.
в моем примере файлы не фильтруются по расширению, небыло необходимости.
могу поделиться кодом.
ниписано безо всяких специальных библиотек библиотек...
(с одной формы умеет загружать сразу несколько файлов)

Код

package org.umek.bts;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// import java.lang.*;
import java.util.*;
import java.sql.*;
// import java.net.URLDecoder;
//==============================================================================
class FileInfo{
        //----------------------------------------------------------------------
        public String filename;
        public int start_index;
        public int last_index;
        //----------------------------------------------------------------------
        public String ToTranslit(String in){
                String alpha = "абвгдеёжзиыйклмнопрстуфхцчшщьэюя ";
                String[] _alpha = { "a","b","v","g","d","e","yo","g","z","i","y","i",
                                    "k","l","m","n","o","p","r","s","t","u",
                                    "f","h","tz","ch","sh","sh","'","e","yu","ya","_"};
                in = in.toLowerCase();
                StringBuffer nname = new StringBuffer("");
                char[] chs = in.toCharArray();
                for(int i=0; i<chs.length;i++){
                    int k = alpha.indexOf(chs[i]);
                    if(k != -1){
                        nname.append(_alpha[k]);
                    }else{
                        nname.append(chs[i]);
                    }
                }
                return nname.toString();
        }
        //----------------------------------------------------------------------
        public FileInfo(String filename, int start_index, int last_index){
           this.filename = filename;
           this.start_index = start_index;
           this.last_index = last_index;
        }
        //----------------------------------------------------------------------
        public void SaveFile (byte[] data, String directory, String bugid){
           if (!filename.equals("NO_FILE")){
              File f = new File(directory + bugid + "_" + ToTranslit(filename));
              try{
                   FileOutputStream fos = new FileOutputStream(f);
                   int length = last_index - start_index;
                   fos.write(data, start_index, length);
                   fos.close();
              }catch(Exception ex){
                   System.out.println(ex.toString());
              }
           }
        }
        //----------------------------------------------------------------------
}
//==============================================================================
public class Upload extends HttpServlet {
        Connection conn     = null;
        Statement stm       = null;
        String SQL          = "";
        HttpSession session = null;
        // String patch = "D:\\proj1\\trunk\\web\\uploads\\";
        String patch = "C:\\apache-tomcat\\webapps\\bts\\uploads\\";
        //----------------------------------------------------------------------
        public String ToTranslit(String in){
                String alpha = new String("абвгдеёжзиыйклмнопрстуфхцчшщьэюя ");
                String[] _alpha = {"a","b","v","g","d","e","yo","g","z","i","y","i","k","l","m","n","o","p","r","s","t","u", "f","h","tz","ch","sh","sh","'","e","yu","ya","_"};
                in = in.toLowerCase();
                StringBuffer nname = new StringBuffer("");
                char[] chs = in.toCharArray();
                for(int i=0; i<chs.length;i++){
                    int k = alpha.indexOf(chs[i]);
                    if(k != -1){
                        nname.append(_alpha[k]);
                    }else{
                        nname.append(chs[i]);
                    }
                }
                return nname.toString();
        }
        //----------------------------------------------------------------------
        @Override
        public void doPost (HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
             byte[] data;
             final int size = 1024*1024;
             session = request.getSession(true);
             PrintWriter out = response.getWriter();
             ServletInputStream in = request.getInputStream();
             BufferedInputStream bf = new BufferedInputStream((InputStream)in, size);
             byte[] all_data = new byte[size];
             int b,j = 0;
             while ((b = bf.read()) != -1){
                  all_data[j] = (byte)b;
                  j++;
             }
             data = new byte[j];
             for(int i=0; i<j; i++){
                     data[i] = all_data[i];
             }
             all_data = null;
             String boundary = extractBoundary(request.getHeader("Content-Type"));
             FileInfo[] file = extractFiles(data, boundary);             
             try{
                 conn = (Connection)session.getAttribute("connect");
                 stm  = conn.createStatement();
                 for (int i=0; i < file.length; i++){                                        
                     file[i].SaveFile(data, patch, request.getParameter("bugid"));
                     if (!file[i].filename.equals("NO_FILE")){
                        SQL ="insert"; // тут запись в бд о файле
                        stm.execute(SQL);
                        stm.execute("commit");
                     }
                 }
                 stm.close();
                 out.print("<meta http-equiv=\"Refresh\" content=\"0; URL=sb?bugid="+request.getParameter("bugid")+"\">");
             }catch(SQLException ex){
                 ex.getStackTrace();
             }
        }
        //----------------------------------------------------------------------
        private String getFilename(String header){
               String filename  = "";
               header.toLowerCase();
               int index;
               if ((index = header.indexOf("filename=")) != -1){
                   int up_index = header.indexOf((int)'"',index + 1 + 9);
                   filename = header.substring(index + 9 + 1, up_index);
                   index = filename.lastIndexOf((int)'/');
                   up_index = filename.lastIndexOf((int)'\\');
                   filename = filename.substring(Math.max(index, up_index) + 1);
               }else{
                    filename = "NO_FILE";
               }
               return filename;
        }
        //----------------------------------------------------------------------
        private void extractData(FileInfo fis, String data){
           char[] ch = {'\r','\n','\r','\n'};
           String new_line = new String(ch);
           String header;
           int index = data.indexOf(new_line,2);
           if (index != -1){
                header = data.substring(0,index);
                fis.filename = getFilename(header);
                fis.start_index += index + 4;
           }
        }
        //----------------------------------------------------------------------
        private FileInfo[] extractFiles(byte[] data, String boundary){
           int i = 0, index = 0, prev_index = 0;
           String data_str = new String(data);
           Vector data_vec = new Vector();
           while((index = data_str.indexOf(boundary,index)) != -1){
              if (i != 0){
               FileInfo f_info =
                new FileInfo("NO_FILE", prev_index, index - 2);
                extractData(f_info,
                data_str.substring(prev_index,index));
                data_vec.addElement(f_info);
              }
              index += boundary.length();
              prev_index = index;
              i++;
           }
           FileInfo[] Data = new FileInfo[i-1];
           Enumeration enume = data_vec.elements();
           i=0;
           while(enume.hasMoreElements()){
                   Data[i] = (FileInfo) enume.nextElement();
                   i++;
           }
           return Data;
        }
        //----------------------------------------------------------------------
        private String extractBoundary(String str){
           int index = str.lastIndexOf("boundary=");
           String boundary = str.substring(index + 9);
           boundary = "--" + boundary;
           return boundary;
        }
        //----------------------------------------------------------------------
}

Автор: iluvatar 21.4.2010, 13:06
0x00, спасибо
Правда, смутили имена методов с большой буквы

Автор: askell 21.4.2010, 21:34
Цитата(gelo86 @ 1.2.2010,  09:44)
Цитата(magicfly @  27.1.2010,  18:15 Найти цитируемый пост)
например идет запрос вида <img src=http.../>


1. Часто мы создаем war, в котором должны быть рисунки. Если они появляются динамически, то после редеплоя (стераем старый и копируем новый war), все картинки теряются. Возможно както tomcat v5,v6 или jetty v6 настроить так, чтобы при теге <img src='path' /> рисунков искал не относительно распакованного war'а, а относительно савсем другой директории (даже хоть на другом диске) ?

2. Стоит ли сохранять дополнительно в базе данных рисунки ? Вдруг ктото стерет с диска фаилы ? Ето безопасно ?

А какая разница?? Нельзя ли  создать папку в webapp где будешь хранить или деплойть файлы??? а доступ будет через контекс: http://url:port/image_store/my_images.png. Ты везде будешь указывать <img src="/image_store/my_images.png"/>

Автор: 0x00 22.4.2010, 06:59
Цитата(iluvatar @ 21.4.2010,  13:06)
0x00, спасибо
Правда, смутили имена методов с большой буквы

просто всю жизнь писал на си++ и вот теперь работа завставляет все делать на яве)
там еще в обоих классах один из методов дублируется)

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