Qual a melhor maneira para zipar um anexo usando Spring para enviar email?

11 respostas
Pedrosa

Tenho o seguinte método para enviar email pelo Spring, preciso zipar o anexo para enviar o email, qual a melhor maneira para pegar esse anexo que chega em um array de byte e zipar, alguém já implementou algo parecido?

protected void enviarEMail(String from, String to,String subject, String corpo, String nomeAnexo, byte[] anexo) throws Exception {
		if (!subject.equals("")) {
			
			SimpleMailMessage msg = new SimpleMailMessage(getMessage());
			msg.setSubject(subject);
			msg.setText(subject);

			MimeMessage message = getMailSender().createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
			
			helper.setTo(to);
			helper.setFrom(from);
			
			helper.setSubject(subject);
			
			if (anexo != null) {
				helper.addAttachment(nomeAnexo, new InputStreamResourceImpl(anexo));
			} else {
				if (corpo.equals("")) {
					corpo = "#";
				}
			}
			helper.setText(corpo);
			System.out.println("vou enviar o mail..");
			getMailSender().send(message);
			
			message = null;
			helper = null;
			msg = null;
		}
	}

11 Respostas

Guilherme_Gomes

Acho que você pode começar aqui pelo proprio GUJ

Pedrosa

O metodo para zipar eu conheço porem minha aplicação é web, não estou trabalhando diretamente com o arquivo e sim com seu array de bytes.

O metodo addAttachment do Spring aceita um InputStreamSource ou um File.

Meu caso é o seguinte tem upload feito com o JSF usando a classe:

org.apache.myfaces.custom.fileupload.UploadedFile

O JSF armazena esse arquivo, talvez em uma pasta temporaria não tem existe um local definido na aplicação, com isso chamo o metodo que envia o email, passando o array de bytes para o metodo addAttachment do Spring, talvez precise zipar esse arquivo na hora que é feito o upload, se tivesse o arquivo fisicamente simplesmente zipava e passava para o addAttachment que aceita um File.

Alguém tem uma luz?

Fabio_Kung

Oi Pedrosa,

Acho que um bom caminho é usar a ZipOutputStream para zipar o array de bytes:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/zip/ZipOutputStream.html

Combina ela com a ByteArrayOutputStream para ter um array de bytes zipado como saída:

http://java.sun.com/j2se/1.5.0/docs/api/java/io/ByteArrayOutputStream.html

Boa sorte!

celso.martins

Há um tempo atrás, postei isso aqui.

Sempre que precisei, funcionou bem…

Alguém não recomenda o uso? Por que?

Obrigado.

Pedrosa

O metodo para Zipar um array de bytes consegui, mas não gera o zip corretamente:

public byte[] zipaImputStream(byte[] input) {
		Deflater compressor = new Deflater();
		compressor.setLevel(Deflater.BEST_COMPRESSION);
		compressor.setInput(input);
		compressor.finish();
		ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
		// Compress the data
		byte[] buf = new byte[1024];
		while (!compressor.finished()) {
			int count = compressor.deflate(buf);
			bos.write(buf, 0, count);
		}
		try {
			bos.close();
		} catch (IOException e) {
		}
		byte[] compressedData = bos.toByteArray();
		return compressedData;

}

Conforme o Kung disse preciso mesclar com a classe ZipOutputStream, alguma idéia para adaptar esse metodo?

von.juliano

Como assim não gera corretamente?

Flw! :thumbup:

Pedrosa

Por que na verdade esse método compacta um array de bytes e não gera um zip em si, mas todos os exemplos que tenho de zipar são com arquivos existentes e não com Array de bytes.

Fabio_Kung

Mas o array de bytes resultante do processo é o zip.

Eu só sugiro que você tente primeiro com a ZipOutputStream, no lugar da Deflate.

Pedrosa

Esta assim agora:

public byte[] zipaImputStream(byte[] input) {
		int i, cont;
		ZipOutputStream zipar = null;
		ZipEntry entry = null;
		BufferedInputStream buffer = null;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
			zipar = new ZipOutputStream(bos);
			zipar.setLevel(0);
			byte[] dados = new byte[TAM_BUFFER];
			buffer = new BufferedInputStream(bos, TAM_BUFFER); //nao compila
			entry = new ZipEntry(bos);//nao compila
			zipar.putNextEntry(entry);nao compila
			while ((cont = buffer.read(dados, 0, TAM_BUFFER)) != -1) {
				zipar.write(dados, 0, cont);
			}
			buffer.close();
			zipar.close();
			
			byte[] compressedData = bos.toByteArray();
			return compressedData;
		}catch (Exception e) {
			e.printStackTrace();
		}
}

Nas linhas

buffer = new BufferedInputStream(bos, TAM_BUFFER);
entry = new ZipEntry(bos);//

Não compilam pois precisam receber um FileInputStream e um File, o que preciso mudar para funcionar?

Pedrosa

Na verdade o metodo addAttachment do Spring recebe um File ou ImputStreamSource, a classe da aplicação InputStreamResourceImpl implementa a InputStreamSource, a briga continua o que devo mudar nesse metodo abaixo para mandar um array de bytes zipado?

public byte[] zipaImputStream(byte[] input) {
		int cont;
		ZipOutputStream zipar = null;
		
		BufferedInputStream buffer = null;
		byte[] compressedData = null;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
			zipar = new ZipOutputStream(bos);
			zipar.setLevel(0);
			byte[] dados = new byte[TAM_BUFFER];
			buffer = new BufferedInputStream(imputStream, TAM_BUFFER);// que não tenho
			//entry = new ZipEntry(); //devo usar essa linha?
			//zipar.putNextEntry(entry); //devo usar essa linha?
			while ((cont = buffer.read(dados, 0, TAM_BUFFER)) != -1) {
				zipar.write(dados, 0, cont);
			}
			buffer.close();
			zipar.close();
			
			compressedData = bos.toByteArray();
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		return compressedData;
		
}
Pedrosa

Alguém tem ideia do que posso fazer aqui?

Criado 14 de maio de 2009
Ultima resposta 18 de mai. de 2009
Respostas 11
Participantes 5