Хранение файлов на сервере java

190
07 ноября 2018, 15:20

Загружаю файл на сервер java.

Отправляю XMLHttpRequest с клиента, содержащий тот самый файл, на RESTful service, который получает файл, читает первые 1024 байта, делает по ним хеш с помощью SHA-256, создаёт каталог с тройной вложенностью и туда временно пишет файл, а затем возвращаем путь к нему клиенту.

Вот соответствующий код:

@POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.APPLICATION_JSON)
    public Response uploadFile(@FormDataParam("file") InputStream is,
                               @FormDataParam("file") FormDataContentDisposition fileDetail,
                               @FormParam("type") String uploadType){
        /*
        * Получаем имя загруженного файла, чтобы вытащить из него расширение
        * */
        String oldFileName = fileDetail.getFileName();
        String ext = oldFileName.substring(oldFileName.lastIndexOf(".")+1, oldFileName.length());
        /*
        * Создаём строку и добавляем к ней путь загрузки всех файлов
        * */
        StringBuilder newFileName = new StringBuilder();

        OutputStream os = null;
        try {
            /*
             * Создаём буфер и читаем в него первые 1024 байта,
             * по ним мы будем хешировать файл
             * */
            byte[] buffer = new byte[1024];
            int read = is.read(buffer);
            HasherClass hasher = new HasherClass( HashType.SHA_256 );
            String hash = hasher.hash(buffer);
            /*
             * Создаём директорию
             * */
            newFileName.append(hash.substring(0, 2)).append(File.separator)
                    .append(hash.substring(2, 4)).append(File.separator)
                    .append(hash.substring(4,6)).append(File.separator);
            String dirPath = newFileName.toString();
            File dir = new File(uploadPath + dirPath);
            if(!dir.exists()){
                dir.mkdirs();
            }
            /*
             * Создаем путь к самому файлу и проверяем на его несуществование,
             * если он существует, то возвращаем ошибку
             * */
            String filePath = newFileName.append(hash.substring(6, hash.length()))
                    .append(ext).toString();
            File file = new File(uploadPath + filePath);
            if(file.exists()){
                return Response.status(Response.Status.CONFLICT)
                        .entity(
                                Json.createObjectBuilder().add("exception", "Файл уже существует").build()
                        ).build();
            }
            /*
            * Создаём поток вывода и проверяем, если файл меньше 1024 байт, то пишет только буфер и возвращаем,
            * иначе пишем весь файл до конца
            * */
            os = new FileOutputStream(file);
            if(read < 1024){
                os.write(buffer, 0, read);
            }else{
                while((read = is.read(buffer)) != -1){
                    os.write(buffer, 0, read);
                }
            }
            /*
            * Помечаем файл как временный, по истечению часа он будет удален,
            * если не используется
            * */
            tempFiles.put(filePath, new Date());
        }catch (IOException e) {
            Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                    .entity(
                            Json.createObjectBuilder().add("exception", "Не удалось загрузить файл").build()
                    ).build();
        }finally {
            try {
                if(os != null) {
                    os.flush();
                    os.close();
                }
            }catch (IOException  e){}
        }
        return Response.ok(
                Json.createObjectBuilder().add("fileName", newFileName.toString())
        ).build();
    }

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

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

У меня возникают вопросы:

1) правильно ли делать хеш по первым 1024 байтам, или можно это сделать как-то по другому

2) правильно ли создавать временный файл а потом его уже перемещать и обрабатывать

3)Иные ошибки

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

READ ALSO
Почему @RequestParam отсутствует

Почему @RequestParam отсутствует

есть метод который вернет ответы с помощью id

216
Как создать массив с буквами кириллицы в Java?

Как создать массив с буквами кириллицы в Java?

При создании массива с русскими символами компилятор выдаёт такую ошибку(смизображение)

189
Java EE Glassfish ProgrammaticLogin. &ldquo;No LoginModules configured for default&rdquo;

Java EE Glassfish ProgrammaticLogin. “No LoginModules configured for default”

Доброго всем времени суток! Столкнулся с ошибкой "No LoginModules configured for default" при попытке вызвать @Remote EJB метод с проверкой роли пользователяАвторизации...

188