Uploading file to java server.
I send XMLHttpRequest from the client containing the same file to the RESTful service that receives the file, reads the first 1024 bytes, makes a hash with it using SHA-256, creates a directory with a triple nesting and temporarily writes the file, and then returns the path to it to the client.
Here is the corresponding code:
@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(); } Also, the files are placed in a temporary directory, from which, after an hour, will be deleted by the daemon if not used.
When using this file (creating a post with images, changing the user's image) it will be deleted from the temporary directory, and also processed (for example, the image will be divided into 3 sizes and compressed before them), and placed in the main directory.
I have questions:
1) Is it correct to make a hash on the first 1024 bytes, or can it be done somehow in another way?
2) is it correct to create a temporary file and then move and process it
3) Other errors
Maybe someone more experienced will tell you what I'm doing wrong / what can be done better, correct, I will be very happy.