Téléchargement groupé de fichiers ZIP en Java pour les packs d'images produit

Voici un exemple d'implémentation permettant de regrouper plusieurs fichiers d'images (stockés en base de données) dans une archive ZIP pour téléchargement. L'extrait suivant illustre une approche possible avec Spring MVC.

Logique du contrôleur

Le contrôleur traite la requête de téléchargement groupé. Il récupère d'abord les noms des paquets correspondant à une famille et un type de produit, puis récupère les données binaires de chaque paquet, et enfin génère un fichier ZIP contenant tous ces paquets.

@Controller
public class ArchiveDownloadController {
    @Autowired
    private ImageArchiveService archiveService;

    @RequestMapping(value = "/archive/batch", method = RequestMethod.GET)
    public void handleBatchArchiveRequest(
            HttpServletResponse response,
            @RequestParam String family,
            @RequestParam String type) throws IOException {
        
        // Décodage des paramètres de requête
        String decodedFamily = new String(family.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        String decodedType = new String(type.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        
        // Récupération des noms de paquets
        List<String> archiveNames = archiveService.findArchiveNames(decodedFamily, decodedType);
        
        if (archiveNames.isEmpty()) {
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
            return;
        }
        
        // Récupération des contenus des paquets
        Map<String, byte[]> archiveData = archiveService.fetchArchives(archiveNames);
        
        // Construction du nom du fichier ZIP
        String zipFilename = decodedFamily + "_" + decodedType + ".zip";
        
        // Génération du ZIP
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", 
            "attachment; filename=" + URLEncoder.encode(zipFilename, "UTF-8"));
        
        try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
            for (Map.Entry<String, byte[]> entry : archiveData.entrySet()) {
                ZipEntry zipEntry = new ZipEntry(entry.getKey());
                zos.putNextEntry(zipEntry);
                zos.write(entry.getValue());
                zos.closeEntry();
            }
        }
    }
}

Service de gestion des archives

@Service
public class ImageArchiveService {
    @Autowired
    private ImageRepository imageRepository;

    public List<String> findArchiveNames(String family, String type) {
        return imageRepository.findArchiveNamesByCategory(family, type);
    }

    public Map<String, byte[]> fetchArchives(List<String> archiveNames) {
        Map<String, byte[]> result = new HashMap<>();
        for (String name : archiveNames) {
            ImageArchive archive = imageRepository.findByArchiveName(name);
            if (archive != null && archive.getBinaryContent() != null) {
                result.put(name, archive.getBinaryContent());
            }
        }
        return result;
    }
}

Couche d'accès aux données

@Repository
public interface ImageRepository extends JpaRepository<ImageArchive, Long> {
    
    @Query("SELECT a.archiveName FROM ImageArchive a " +
           "JOIN a.product p " +
           "WHERE p.productFamily = :family AND p.productType = :type")
    List<String> findArchiveNamesByCategory(
        @Param("family") String family, 
        @Param("type") String type);
    
    ImageArchive findByArchiveName(String name);
}

Structure des entités

@Entity
@Table(name = "image_archives")
public class ImageArchive {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(unique = true)
    private String archiveName;
    
    @Lob
    private byte[] binaryContent;
    
    @ManyToOne
    @JoinColumn(name = "product_id")
    private Product product;
    
    // Getters et setters
}

@Entity
@Table(name = "products")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String productFamily;
    private String productType;
    
    // Getters et setters
}

Étiquettes: Java Spring MVC ZIP Archive Batch Download BLOB

Publié le 15 juin à 18h45