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");
}
}
1 answers
On dirait qu'il y a en fait deux problèmes ici:
-
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
. - 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.