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


Автор: webmaster35 31.1.2010, 21:42
В книжке есть пример загрузки файлов на сервер. Привожу код JSP обработчика :

Код
<%@ page import="java.io.*" %>

<%

String savePath = "D:\\123\\";

String filename = "";

ServletInputStream in = request.getInputStream();

byte[] line = new byte[128];
int i = in.readLine(line, 0, 128);
int boundaryLength = i - 2;
String boundary = new String(line, 0, boundaryLength);

while (i != -1) {
    String newLine = new String(line, 0, i);
    if (newLine.startsWith("Content-Disposition: form-data; name=\"")) {
        String s = new String(line, 0, i-2);
    int pos = s.index0f("filename=\"");
    if (pos != -1) {
        String filepath = s.substring(pos+10, s.length()-1);
        pos = filepath.lastIndex0f("\\");
        if (pos != -1)
            filename = filepath.substring(pos + 1 );
        else
             filename = filepath;
}

i = in.readLine(line, 0, 128);
i = in.readLine(line, 0, 128);

i = in.readLine(line, 0, 128);

ByteArrayOutputStream buffer = new ByteArrayOutputStream();
newLine = new String(line, 0, i);

while (i != -1 && !newline.startsWith(boundary)) {
    buffer.write(line, 0, i);
    i = in.readLine(line, 0, 128);
    newLine = new String(line, 0, i);
}

try {

  RandomAcessFile f = new RandomAcessFile ( savePath + filename, "rw");
byte[] bytes = buffer.toByteArray();
f.write(bytes, 0, bytes.length - 2);
f.close();
}
catch (Exception e) {}
}
i = in.readLine(line, 0, 128);
}
%>



И возникает вопрос, как этот загруженный на сервер файл отображать , для закачки ?

Автор: MaxPayneC 31.1.2010, 22:33
Если загруженные на сервер файлы должны стать доступны для скачивания впоследствии, есть два пути:
1. Мы сохраняем файлы в один из каталогов веб-приложения, дабы они стали доступы по прямой ссылке.
2. Мы сохраняем файлы в блобы в базу данных, и делаем непрямые ссылки на некий action (servlet, jsp, etc) который вернет нам его, например в виде Content-disposition: attachment.

Автор: webmaster35 1.2.2010, 09:27
Цитата(MaxPayneC @ 31.1.2010,  22:33)
Если загруженные на сервер файлы должны стать доступны для скачивания впоследствии, есть два пути:
1. Мы сохраняем файлы в один из каталогов веб-приложения, дабы они стали доступы по прямой ссылке.
2. Мы сохраняем файлы в блобы в базу данных, и делаем непрямые ссылки на некий action (servlet, jsp, etc) который вернет нам его, например в виде Content-disposition: attachment.

Как я понимаю 2-ой способ более хорош, позволяет нормально управлять файлами и т.д. Примеры на него есть ?

Автор: MaxPayneC 1.2.2010, 10:45
Пример с использованием фреймворка Struts 2:
Код аплоада:
Код

public class UpdateProfile extends AbstractAction          
{
....
    /**
     * Загруженная фотка
     */                 
    private File photo; 

    /**
     * MIME-тип загруженной фотки
     */                          
    private String photoContentType;
...
    @Override                                                                                                                   
    public String execute()
    {
....
            if (getPhoto() != null) //если в форме была указана фотка, которую надо залить
            {                                                                             
                GraduatePhoto photo = stored_gr.getPhoto();                               
                if (photo == null)                                                        
                {                                                                         
                    photo = new GraduatePhoto();                                          
                }                                                                         
                photo.setMimeType(getPhotoContentType());                                 
                photo.setContent(getPhoto());                                             
                hb_session.save(photo);                                                   
                stored_gr.setPhoto(photo);                                                
            } 

....
    }
....
}


Код получения блоба из файла:
Код

    /**                                                               
     * Содержимое файла.                                              
     */                                                               
    private Blob content;                                             
    /**                                                               
     * MIME-тип файла.                                                
     */                                                               
    private String MimeType;

....

    public void setContent(File content) throws IOException
    {
        this.content = Hibernate.createBlob(Utils.getBytesFromFile(content));
    }


И наконец, код возврата этого файла пользователю (в примере - картинки):
Код

            PhotoType photoType = PhotoType.getPhotoTypeByString(photo_type);                                                    
            Photo photo = photoType.getPhoto(Integer.parseInt(photo_id));                                                        
            BufferedImage img = ImageIO.read(photo.getContent().getBinaryStream()); //делаем из блоба буффередимж                
            int w, h;                                                                                                            
            if ((width == null) || (width.trim().isEmpty())) //В этом случае ресайзим по нему пропорционально высоте             
            {                                                                                                                    
                w = -1;                                                                                                          
            }                                                                                                                    
            else //Если тип изображения имеет ограничение по ширине, берем минимум из этого ограничения и желаемой ширины        
            {                                                                                                                    
                w = photoType.maxWidth != null ? Math.min(Integer.parseInt(width), photoType.maxWidth) : Integer.parseInt(width);
            }                                                                                                                    

            if ((height == null) || (height.trim().isEmpty())) //в этом случае ресайзим по нему пропорционально ширине
            {                                                                                                         
                h = -1;                                                                                               
            }                                                                                                         
            else //Если тип изображения имеет ограничение по высоте, берем минимум из этого ограничения и желаемой высоты
            {                                                                                                            
                h = photoType.maxHeight != null ? Math.min(Integer.parseInt(height), photoType.maxHeight) : Integer.parseInt(height);
            }                                                                                                                        

            BufferedImage resultImage;
            if ((w == -1) && (h == -1)) //ресайз не требуется, в этом случае уменьшаем фото до допустимого максимума, если она больше него
            {                                                                                                                             
                w = photoType.maxWidth != null ? Math.min(photoType.maxWidth, img.getWidth()) : img.getWidth();                           
                h = photoType.maxHeight != null ? Math.min(photoType.maxHeight, img.getHeight()) : img.getHeight();                       
            }                                                                                                                             
            resultImage = Utils.resizeImage(img, w, h, RenderingHints.VALUE_INTERPOLATION_BICUBIC); //ресайзим с бикубической интерполяцией

            ByteArrayOutputStream output = new ByteArrayOutputStream();

            //"Кладем" нашу ресайзнутую фотку в поток. Вот тут особенно сильное шаманство:
            //Т.к. в базе хранится майм-тип, т.е. image/xxxx (для картинок), а ImageIO.write такой формат не нравится, вырезаем из строки первые шесть символов.
            ImageIO.write(resultImage, photo.getMimeType().substring(6), output);                                                                               

            //получаем из буфферед-имж байт[]
            byte[] photoBytes = output.toByteArray();

            //вывести фотку через поток ServletOutputStream
            ServletOutputStream str = response.getOutputStream();

            str.write(photoBytes);
            str.close();


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

Автор: webmaster35 1.2.2010, 17:33
Цитата(MaxPayneC @ 1.2.2010,  10:45)
Пример с использованием фреймворка Struts 2:


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


Одним словом охренеть ... На русском инфа по "струтсу" есть ? Или только на англ ? Я пока фреймворки не трогал, для меня там честно говоря полный темный лес, хотя ДАО шаблон немного освоил и понял .

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

Автор: serger 2.2.2010, 11:44
Цитата(webmaster35 @  1.2.2010,  17:33 Найти цитируемый пост)
Вот этот метод по которому ты показал пример это помещение файла в базу ? Просто говорят что так делать не надо, нагрузка большая будет, лучше просто на диске файлы хранить

зависит от ситуации, но лучше да, так не делать.

Автор: MaxPayneC 2.2.2010, 15:55
Да, я файлы хранил в блобах в базе.

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