Extraction de Fichier Zip Java


J'ai un gestionnaire de planification GTFS qui télécharge automatiquement un fichier compressé à partir d'une URL de fournisseur spécifiée et en extrait les fichiers à la volée dans un dossier spécifié. Donc, à la fin de ce processus, le dossier contient uniquement les fichiers extraits et non le fichier compressé lui-même.

Cela a jusqu'à présent toujours fonctionné mais avec

Http://mta.maryland.gov/_googletransit/latest/google_transit.zip

Cela ne fonctionne pas pour une raison quelconque. Quand je vais à obtenir le première entrée zip du flux, il est null. Je peux cependant télécharger manuellement le fichier compressé dans un dossier local, y modifier l'URL de mon application java et l'extraire correctement. C'est juste l'extraction à la volée qui ne fonctionne pas.

Ceci est démontré en exécutant le code ci-dessous tel quel: vous verrez l'échec. Si vous téléchargez ensuite le fichier compressé manuellement dans le dossier" feeds "et échangez autour des "extractFilesFromFeed" commentés.extract " lignes principales sous l'extraction travail.

La question est de savoir s'il y a un changement que je peux faire ci-dessous afin que cette URL particulière puisse être extraite à la volée ?

===

import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ExtractFilesFromFeed {

  private Logger logger = Logger.getLogger("");

  public void extract(String feedLocation, String feedFolder) throws Exception  {
    if (feedLocation == null || feedLocation.length() == 0) {
      String tmp = "Invalid feed location specified for GTFS schedule file extraction";
      throw new Exception(tmp);
    }
    else if (feedFolder == null || feedFolder.length() == 0) {
      String tmp = "Invalid feed folder specified for GTFS schedule file extraction";
      throw new Exception(tmp);
    }
    else {
      logger.log(Level.INFO, String.format("Extracting GTFS schedule files from %s to %s", 
          feedLocation, feedFolder));
    }

    URL url;
    if (feedLocation.startsWith("http")) {
      url = new URL(feedLocation);
    }
    else {
      url = new File(feedLocation).toURI().toURL();
    }

    File dir = new File(feedFolder);
    if(!dir.exists()){
      dir.mkdir();
    }

    byte[] buffer = new byte[8192];
    ZipInputStream zis = new ZipInputStream(url.openStream());
    ZipEntry ze = zis.getNextEntry();

    if (ze == null) {
      logger.log(Level.WARNING, "Unable to get first entry from zip file, aborting download");
      zis.close();
      throw new Exception(String.format("Unable to get first entry from zip file %s", feedLocation));
    }

    while (ze != null){
      String zipFileName = ze.getName();
      if (ze.isDirectory()) {
        dir = new File(feedFolder + "/" + zipFileName);
        if(!dir.exists()){
          dir.mkdir();
        }
      }
      else {
        FileOutputStream fos = new FileOutputStream(feedFolder + File.separator + zipFileName);
        int len;
        while ((len = zis.read(buffer)) > 0) {
          fos.write(buffer, 0, len);
        }
        fos.close();   
      }
      ze = zis.getNextEntry();
    }
    zis.close();
  }

  public static void main(String[] args) throws Exception {
    ExtractFilesFromFeed extractFilesFromFeed = new ExtractFilesFromFeed();
    extractFilesFromFeed.extract("http://mta.maryland.gov/_googletransit/latest/google_transit.zip", "feeds");
    //extractFilesFromFeed.extract("feeds/google_transit.zip", "feeds");
  }
}
Author: paulh, 2017-03-28

1 answers

On dirait qu'il y a en fait deux problèmes ici:

  1. http://mta.maryland.gov/_googletransit/latest/google_transit.zip a une redirection HTTP 301 vers une version SSL sécurisée à https://mta.maryland.gov/_googletransit/latest/google_transit.zip.
  2. La prise de contact SSL peut échouer en raison du manque de fichiers de stratégie de sécurité

Pour la redirection, vous devrez utiliser quelque chose comme ce qui suit:

URL url;
if (feedLocation.startsWith("http")) {
    url = new URL(feedLocation);
    URLConnection urlConnection = url.openConnection();
    // Check for HTTP 301 redirect
    String redirect = urlConnection.getHeaderField("Location");
    if (redirect != null) {
        logger.log(Level.WARNING, "Redirecting to " + redirect);
        url = new URL(redirect);
    }
} else {...

Ensuite, lors de l'ouverture du flux d'entrée, vous voudrez probablement attraper et enregistrer tout SSLHandshakeExceptions:

try {
    ZipInputStream zis = new ZipInputStream(url.openStream());
    ...
} catch (SSLHandshakeException sslEx) {
    logger.log(Level.ERROR, "SSL handshake failed.  Try installing the JCE Extension - see http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html");
}

Pour installer l'extensionJCE , vous devrez remplacer le US_export_policy.jar et local_policy.jar fichiers dans votre répertoire JVM /security, tels que C:\Program Files\Java\jdk1.8.0_73\jre\lib\security, avec les fichiers JAR dans le téléchargement de l'extension JCE.

Je viens de résoudre ce même problème dans notre projet-le commit qui a résolu le problème est https://github.com/CUTR-at-USF/gtfs-realtime-validator/commit/180785d22ca58afa2463b322ad4e1b122c5f0a30, et le problème Github pour le problème était https://github.com/CUTR-at-USF/gtfs-realtime-validator/issues/89.

Crédit à 301 Déplacé En permanence pour la solution de redirection HTTP 301 et https://stackoverflow.com/a/30760134/937715 pour installer l'extension JCE.

 1
Author: Sean Barbeau, 2017-05-23 10:30:58