varios - Archivo zip protegido por contraseña en java
comprimir varios archivos en un zip con java (4)
El código de muestra a continuación se comprimirá y la contraseña protegerá su archivo. Este servicio REST acepta bytes del archivo original. Se comprime la matriz de bytes y la contraseña lo protege. Luego envía bytes del archivo comprimido protegido por contraseña como respuesta. El código es una muestra de cómo enviar y recibir bytes binarios desde y hacia un servicio REST, y también de comprimir un archivo con protección de contraseña. Los bytes están comprimidos de la secuencia, por lo que nunca se almacenan archivos en el servidor.
- Utiliza la API de JAX-RS usando la API de Jersey en java
- El cliente está utilizando la API de Jersey-client.
- Utiliza la biblioteca de código abierto zip4j 1.3.2 y apache commons io.
@PUT
@Path("/bindata/protect/qparam")
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response zipFileUsingPassProtect(byte[] fileBytes, @QueryParam(value = "pass") String pass,
@QueryParam(value = "inputFileName") String inputFileName) {
System.out.println("====2001==== Entering zipFileUsingPassProtect");
System.out.println("fileBytes size = " + fileBytes.length);
System.out.println("password = " + pass);
System.out.println("inputFileName = " + inputFileName);
byte b[] = null;
try {
b = zipFileProtected(fileBytes, inputFileName, pass);
} catch (IOException e) {
e.printStackTrace();
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
System.out.println(" ");
System.out.println("++++++++++++++++++++++++++++++++");
System.out.println(" ");
return Response.ok(b, MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition", "attachment; filename = " + inputFileName + ".zip").build();
}
private byte[] zipFileProtected(byte[] fileBytes, String fileName, String pass) throws IOException {
ByteArrayInputStream inputByteStream = null;
ByteArrayOutputStream outputByteStream = null;
net.lingala.zip4j.io.ZipOutputStream outputZipStream = null;
try {
//write the zip bytes to a byte array
outputByteStream = new ByteArrayOutputStream();
outputZipStream = new net.lingala.zip4j.io.ZipOutputStream(outputByteStream);
//input byte stream to read the input bytes
inputByteStream = new ByteArrayInputStream(fileBytes);
//init the zip parameters
ZipParameters zipParams = new ZipParameters();
zipParams.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
zipParams.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
zipParams.setEncryptFiles(true);
zipParams.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
zipParams.setPassword(pass);
zipParams.setSourceExternalStream(true);
zipParams.setFileNameInZip(fileName);
//create zip entry
outputZipStream.putNextEntry(new File(fileName), zipParams);
IOUtils.copy(inputByteStream, outputZipStream);
outputZipStream.closeEntry();
//finish up
outputZipStream.finish();
IOUtils.closeQuietly(inputByteStream);
IOUtils.closeQuietly(outputByteStream);
IOUtils.closeQuietly(outputZipStream);
return outputByteStream.toByteArray();
} catch (ZipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputByteStream);
IOUtils.closeQuietly(outputByteStream);
IOUtils.closeQuietly(outputZipStream);
}
return null;
}
Prueba unitaria a continuación:
@Test
public void testPassProtectZip_with_params() {
byte[] inputBytes = null;
try {
inputBytes = FileUtils.readFileToByteArray(new File(inputFilePath));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("bytes read into array. size = " + inputBytes.length);
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080").path("filezip/services/zip/bindata/protect/qparam");
target = target.queryParam("pass", "mypass123");
target = target.queryParam("inputFileName", "any_name_here.pdf");
Invocation.Builder builder = target.request(MediaType.APPLICATION_OCTET_STREAM);
Response resp = builder.put(Entity.entity(inputBytes, MediaType.APPLICATION_OCTET_STREAM));
System.out.println("response = " + resp.getStatus());
Assert.assertEquals(Status.OK.getStatusCode(), resp.getStatus());
byte[] zipBytes = resp.readEntity(byte[].class);
try {
FileUtils.writeByteArrayToFile(new File(responseFilePathPasswordZipParam), zipBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
Siéntase libre de usar y modificar. Por favor, hágamelo saber si encuentra algún error. Espero que esto ayude.
Edición 1: uso de QueryParam pero puede usar HeaderParam para PUT en lugar de ocultar el passwd a simple vista. Modificar el método de prueba en consecuencia.
Edición 2: la ruta REST es filezip / services / zip / bindata / protect / qparam
filezip es el nombre de la guerra. servicios es el mapeo de url en web.xml. zip es una anotación de ruta de nivel de clase. bindata / protect / qparam es la anotación de ruta de nivel de método.
He creado un archivo zip usando java como se muestra a continuación
import java.io.*;
import java.util.zip.*;
public class ZipCreateExample {
public static void main(String[] args) throws IOException {
System.out.print("Please enter file name to zip : ");
BufferedReader input = new BufferedReader
(new InputStreamReader(System.in));
String filesToZip = input.readLine();
File f = new File(filesToZip);
if(!f.exists()) {
System.out.println("File not found.");
System.exit(0);
}
System.out.print("Please enter zip file name : ");
String zipFileName = input.readLine();
if (!zipFileName.endsWith(".zip"))
zipFileName = zipFileName + ".zip";
byte[] buffer = new byte[18024];
try {
ZipOutputStream out = new ZipOutputStream
(new FileOutputStream(zipFileName));
out.setLevel(Deflater.DEFAULT_COMPRESSION);
FileInputStream in = new FileInputStream(filesToZip);
out.putNextEntry(new ZipEntry(filesToZip));
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
in.close();
out.close();
} catch (IllegalArgumentException iae) {
iae.printStackTrace();
System.exit(0);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
System.exit(0);
} catch (IOException ioe) {
ioe.printStackTrace();
System.exit(0);
}
}
}
Ahora quiero que cuando haga clic en el archivo zip, debería indicarme que escriba la contraseña y luego descomprima el archivo zip. Por favor, cualquier ayuda, ¿Cómo debo ir más allá?
La API estándar de Java no admite archivos zip protegidos por contraseña. Afortunadamente, los buenos ya han implementado tal habilidad para nosotros. Lea este artículo que explica cómo crear un archivo zip protegido con contraseña: http://java.sys-con.com/node/1258827
No hay una API de Java predeterminada para crear un archivo protegido por contraseña. Hay otro ejemplo sobre cómo hacerlo here .
Pruebe el siguiente código que se basa en Zip4j
:
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
public class Zipper
{
private String password;
private static final String EXTENSION = "zip";
public Zipper(String password)
{
this.password = password;
}
public void pack(String filePath) throws ZipException
{
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_ULTRA);
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
zipParameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
zipParameters.setPassword(password);
String baseFileName = FilenameUtils.getBaseName(filePath);
String destinationZipFilePath = baseFileName + "." + EXTENSION;
ZipFile zipFile = new ZipFile(destinationZipFilePath);
zipFile.addFile(new File(filePath), zipParameters);
}
public void unpack(String sourceZipFilePath, String extractedZipFilePath) throws ZipException
{
ZipFile zipFile = new ZipFile(sourceZipFilePath + "." + EXTENSION);
if (zipFile.isEncrypted())
{
zipFile.setPassword(password);
}
zipFile.extractAll(extractedZipFilePath);
}
}
FilenameUtils
es de Apache Commons IO
.
Ejemplo de uso:
public static void main(String[] arguments) throws ZipException
{
Zipper zipper = new Zipper("password");
zipper.pack("encrypt-me.txt");
zipper.unpack("encrypt-me", "D://");
}