Как создать файл KMZ из KML на лету, используя Java

Я пытаюсь создать файл kmz из файла kml на лету и представить его в виде потока байтов в веб-приложении.

Но когда я скачал сгенерированный файл kmz, я не смог открыть его с помощью диспетчера архивов в Ubuntu.

Я вижу похожие вопросы на этом сайте, но это не работает.

Может кто-нибудь помочь мне и объяснить, что я делаю неправильно?!

Это мой код

@Public public void retrieveKmlInOldFormat() {
   File file = new File(Play.applicationPath+"/"+Play.configuration.getProperty("web.content", "../bspb-web")+"/map/map.kml");
   String kmlFileContent = null;
   try {
     String kmlUrl = file.toURI().toURL().toString();
     kmlFileContent = BSPBKml2OldFormatConverter.toOldKml(
                        kmlParserLocal.load(kmlUrl));
   } catch (MalformedURLException e) {
      e.printStackTrace();
   }
   String zippedFileName = "old_fmt_map.kmz";
   String zippedKml = compressKmlFile(kmlFileContent,zippedFileName);
   response.setContentTypeIfNotSet("application/vnd.google-earth.kmz");
   renderBinary(new ByteArrayInputStream(zippedKml.getBytes()),zippedFileName);
   return;
}

Код метода сжатия:

private String compressKmlFile(String kmlFileContent,String zipEntryName){

String zippedContent = null;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

ZipOutputStream zipStream = new ZipOutputStream(new
  BufferedOutputStream(byteStream));

ZipEntry zipEntry = null;
zipEntry = new ZipEntry("doc.kml");
try {
  zipEntry.setSize(kmlFileContent.getBytes("UTF-8").length);
  zipStream.putNextEntry(zipEntry);
  zipStream.write(kmlFileContent.getBytes("UTF-8"));
  zipStream.closeEntry();      
  zippedContent = new String(byteStream.toByteArray(),"UTF-8");
} catch (IOException e) {
  logger.error("Error while zipping kml file content");
}
finally {
  try {
    byteStream.close();
    zipStream.close();
  } catch (IOException e) {
    logger.error(e.getMessage());
  }
}
return zippedContent;
}

1 ответ

Решение

Проблема в скачанном поврежденном архиве kmz. Эту проблему можно решить, используя поток вывода ответа http в качестве аргумента конструктора для класса ZipOutputStream.

Решение в этом коде.

@Public public void retrieveKmlInOldFormat(){
 File file = new File(Play.applicationPath+"/"+Play.configuration.getProperty("web.content", "../bspb-web")+"/map/map.kml");
 String kmlFileContent = null;
 try {
   String kmlUrl = file.toURI().toURL().toString();
   kmlFileContent = BSPBKml2OldFormatConverter.toOldKml(kmlParserLocal.load(kmlUrl));
 } catch (MalformedURLException e) {
   e.printStackTrace();
 }
 response.setContentTypeIfNotSet("application/vnd.google-earth.kmz");
 response.setHeader("Content-Disposition", "attachment; filename=\"old_fmt_map.kmz\"");
 renderAsKmz(response, kmlFileContent,"old_fmt_map.kml");
 return;
}



private void renderAsKmz(Response response,String kmlFileContent,String zipEntryName){
 ZipOutputStream zipStream = new ZipOutputStream(response.out);
 ZipEntry zipEntry = new ZipEntry(zipEntryName);
 try {
  zipStream.putNextEntry(zipEntry);
  zipStream.write(kmlFileContent.getBytes());
 } catch (IOException e) {
   logger.error("Error while zipping kml file content : " + e.getMessage());
 }
 finally {
   try {
     zipStream.closeEntry();
     zipStream.close();
   } catch (IOException e) {
    logger.error("Error while closing zipped stream : " + e.getMessage());
  }
}
Другие вопросы по тегам