Triển khai chức năng tải lên tệp với Spring Boot và Layui

Ghi chú phát triển chức năng tải lên tệp

Thực hiện chức năng tải lên tệp với giao diện sử dụng thành phần Layui và nền tảng Spring Boot

Mã nguồn giao diện người dùng:

HTML:

<button type="button" class="layui-btn" id="fileUploadBtn">
    <i class="layui-icon">&#xe67c;</i>Tải lên hình ảnh
</button>

JavaScript:

// Xử lý tải lên hình ảnh
var uploadHandler = upload.render({
    elem: '#fileUploadBtn',
    url: '/api/files/upload',
    data: {
        fileType: "1"
    },
    size: 0,
    before: function(obj) {
        // Có thể thêm xử lý trước khi tải lên
    },
    done: function(res) {
        // Nếu tải lên thất bại
        if(res.code > 0) {
            return layer.msg('Tải lên thất bại');
        } else if(res.code === 0) { // Tải lên thành công
            currentDepartment.imageId = res.fileId;
            currentDepartment.imageUrl = res.fileUrl;
        }
    },
    error: function() {
        // Hiển thị trạng thái thất bại và cho phép thử lại
        var statusText = $('#uploadStatus');
        statusText.html('<span style="color: #FF5722;">Tải lên thất bại</span> <a class="layui-btn layui-btn-xs retryBtn">Thử lại</a>');
        statusText.find('.retryBtn').on('click', function(){
            uploadHandler.upload();
        });
    }
});

Mã nguồn phía máy chủ Java:

Cấu hình trong Application.java:

/**  
 * Cấu hình cho việc tải lên tệp  
 * @return  
 */  
@Bean  
public MultipartConfigElement multipartConfigElement() {  
    MultipartConfigFactory factory = new MultipartConfigFactory();  
    // Kích thước tối đa của một tệp  
    factory.setMaxFileSize("10240KB"); // KB, MB  
    // Tổng kích thước dữ liệu tải lên  
    factory.setMaxRequestSize("102400KB");  
    return factory.createMultipartConfig();  
}  

Hằng số định nghĩa đường dẫn:

/**
 * Đường dẫn thư mục chính cho tệp tải lên (mặc định)
 */
private String baseFolder = "C://";
    
/**
 * Tên thư mục con cho tệp từ máy tính
 */
private String pcFolder = "upload/pcfiles/";
    
/**
 * Tên thư mục cho hình ảnh (fileType=1)
 */
private String imageFolder = "image";
    
/**
 * Tên thư mục cho tài liệu (fileType=2)
 */
private String documentFolder = "document";
    
/**
 * Tên thư mục cho video (fileType=3)
 */
private String videoFolder = "video";
    
/**
 * Tên thư mục cho file torrent (fileType=4)
 */
private String torrentFolder = "torrent";
    
/**
 * Tên thư mục cho âm nhạc (fileType=5)
 */
private String musicFolder = "music";
    
/**
 * Tên thư mục cho các tệp khác (fileType=6)
 */
private String otherFolder = "other";

Phương thức xử lý tải lên tệp:

/**
 * Xử lý tải lên một tệp đơn
 * Có thể gọi trực tiếp từ JavaScript hoặc dùng làm API tiện ích
 * Phương thức đồng bộ
 * @param multipartFile Tệp cần tải lên
 * @param destinationPath Đường dẫn lưu trữ (nếu có, không dùng đường dẫn mặc định)
 * @param fileType Loại tệp (1: hình ảnh, 2: tài liệu, 3: video, 4: torrent, 5: nhạc, 6: khác)
 * @return Map chứa kết quả xử lý
 */
@RequestMapping("/api/files/upload")
@ResponseBody
public synchronized Map<String, Object> handleFileUpload(
        MultipartFile multipartFile, 
        String destinationPath, 
        String fileType,
        HttpServletRequest request, 
        HttpServletResponse response) {

    Map<String, Object> responseMap = new HashMap<String, Object>();
    HttpSession session = request.getSession();
    
    try {
        // Lấy thông tin người dùng hiện tại
        User currentUser = (User)session.getAttribute("USER");
        
        // Đường dẫn lưu tệp
        String fileStoragePath ="";
        // URL truy cập tệp
        String accessUrl="";
        
        // Nếu không chỉ định loại, tự động xác định
        if(fileType == null) {
            InputStream fileInput = multipartFile.getInputStream();
            // Xác định loại tệp
            Integer detectedType = FileTypeDetector.determineType(
                                 FileTypeDetector.getMimeType(fileInput));
            fileType = detectedType.toString();
        }
        
        // Xử lý đường dẫn lưu trữ theo loại tệp
        if(destinationPath == null || destinationPath.isEmpty()) {
            fileStoragePath = baseFolder + pcFolder;
            accessUrl = pcFolder;
            
            // Thư mục theo loại tệp
            switch(fileType) {
                case "1": // Hình ảnh
                    fileStoragePath += imageFolder;
                    accessUrl += imageFolder;
                    break;
                case "2": // Tài liệu
                    fileStoragePath += documentFolder;
                    accessUrl += documentFolder;
                    break;
                case "3": // Video
                    fileStoragePath += videoFolder;
                    accessUrl += videoFolder;
                    break;
                case "4": // Torrent
                    fileStoragePath += torrentFolder;
                    accessUrl += torrentFolder;
                    break;
                case "5": // Nhạc
                    fileStoragePath += musicFolder;
                    accessUrl += musicFolder;
                    break;
                default: // Khác
                    fileStoragePath += otherFolder;
                    accessUrl += otherFolder;
            }
        } else {
            fileStoragePath = destinationPath;
        }
        
        // Tạo thư mục nếu chưa tồn tại
        File storageDirectory = new File(fileStoragePath);
        if (!storageDirectory.exists()) {
            storageDirectory.mkdirs();
        }
        
        // Xử lý tên tệp
        String originalFileName = null;
        String fileNameWithoutExt = multipartFile.getOriginalFilename()
                .substring(0, multipartFile.getOriginalFilename().lastIndexOf("."));
        String fileExtension = multipartFile.getOriginalFilename()
                .substring(multipartFile.getOriginalFilename().lastIndexOf("."));
        
        long fileSize = multipartFile.getSize();
        String fileSizeFormatted = formatFileSize(fileSize);
        
        // Lưu thông tin tệp vào cơ sở dữ liệu
        FileInfo fileInfo = new FileInfo();
        fileInfo.setFileName(fileNameWithoutExt);
        fileInfo.setFileType(fileType);
        fileInfo.setFileExtension(fileExtension);
        fileInfo.setFileSize(fileSizeFormatted);
        fileInfo.setCreateTime(new Date());
        fileInfo.setCreateUser(currentUser.getId());
        fileInfo.setUpdateTime(new Date());
        fileInfo.setUpdateUser(currentUser.getId());
        fileInfo.setIsDeleted("1"); // Mặc định ẩn
        fileInfo.setStatus("0"); // Chưa tải lên
        
        fileInfoService.create(fileInfo);
        int fileId = fileInfo.getId();
        
        // Tạo tên tệp mới (UUID + ID tệp)
        String uniqueId = UUID.randomUUID().toString().replaceAll("-", "");
        originalFileName = uniqueId + "_" + fileId + fileExtension;
        
        // Lưu tệp
        multipartFile.transferTo(new File(fileStoragePath, originalFileName));
        
        // Cập nhật thông tin sau khi tải lên thành công
        accessUrl = accessUrl + "/" + originalFileName;
        fileInfo.setFileUrl(accessUrl);
        fileInfo.setIsDeleted("0"); // Hiển thị
        fileInfo.setStatus("1"); // Tải lên thành công
        fileInfoService.update(fileInfo);
        
        // Tạo URL đầy đủ để trả về
        String fullUrl = request.getScheme() + "://" + 
                        request.getServerName() + ":" + 
                        request.getLocalPort();
        
        Map<String, Object> responseData = new HashMap<String, Object>();
        responseData.put("src", fullUrl + "/" + accessUrl);
        
        responseMap.put("code", 0); // Mã thành công cho Layui
        responseMap.put("SUCCESS", true);
        responseMap.put("message", "Tải lên thành công");
        responseMap.put("data", responseData);
        responseMap.put("fileId", fileInfo.getId());
        responseMap.put("fileUrl", accessUrl);
        
        return responseMap;
    } catch (Exception e) {
        e.printStackTrace();
        responseMap.put("SUCCESS", false);
        responseMap.put("message", "Tải lên thất bại");
        return responseMap;
    }
}

/**
 * Định dạng kích thước tệp
 */
private String formatFileSize(long size) {
    // Triển khai định dạng kích thước tệp
    // Ví dụ: KB, MB, GB
    return "Định dạng kích thước tệp";
}

Phần xác định tự động loại tệp

Xem bài viết khác: Xác định tự động loại tệp khi tải lên trong Java

Lưu ý: Phần tương tác với cơ sở dữ liệu cần điều chỉnh cho phù hợp với dự án cụ thể của bạn

Thẻ: Spring Boot layui Java file upload multipart

Đăng vào ngày 17 tháng 6 lúc 16:15