Javamail attachments data lost - java

I use Javamail to save attachments in a temp Folder, code is given below :-
for (int i = 0; i < multipartmsg.getCount(); ++i) {
BodyPart bodypart = multipartmsg.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(bodypart.getDisposition())
&& null != bodypart.getFileName()
&& !bodypart.getFileName().isEmpty()) {
InputStream is = bodypart.getInputStream();
MimeBodyPart mbp = new MimeBodyPart(is);
File f = new File("/temp/"+abcd);
mbp.saveFile(f);
}
But a 250kB file gets saved as 220kB. There is a loss of data, hence I am unable to open the file. Any idea why this may be happening ?
I also set my properties.setProperty("mail.imaps.partialfetch", "false"); since I use imaps to connect.

Why are you creating a new MimeBodyPart with the content of the original part? That makes no sense, and is likely the source of your problem. Just use the saveFile method on the original part.

Related

called a soap web service which returns a zip file as an attachment. How to unzip it in memory?

I have seen posts about how to unzip files using Java, where the zip file is located somewhere on disk. In my case it's different.
I have code which calls a soap web service. The service response includes an attachment which is a zip file. I have been able to get the attachment. here is part of the code:
Iterator<?> i = soapResponse.getAttachments();
Object obj = null;
AttachmentPart att = (AttachmentPart) i.next();
So, I have the zip file as a type "AttachmentPart" however I could also do:
byte[] arr1 = att.getRawContentBytes();
which would give me the array of bytes containing the zip file.
I could also do
Object obj = att.getContent()
So, I can get the zip files in different formats/types. The zip files contains two .csv files and I have to do different stuff to those files. To make my question simpler, all I am looking to do for now is to get the two .csv files and print its content to the console.
I want to do everything in memory. I don't want to put the content of the zip files on disk.
How can I unzip the attachment and print the content?
If you grab the att.getRawContent() from the AttachmentPart object, you can pass it to the built in ZipInputStream to read the contents of the zip file. You can then write the bytes read from the ZipInputStream directly to System.out to view the contents on the console.
Below is an example that should read the zip contents and then write the entry name followed by the entry contents to standard out, assuming you pass it the AttachmentPart that contains the zip file. It will also filter out any entries that are directories so that they are not printed.
public static void printAttachmentPartZip(AttachmentPart att) throws IOException, SOAPException {
try (ZipInputStream zis = new ZipInputStream(att.getRawContent())) {
byte[] buffer = new byte[1024];
for (ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null; zipEntry = zis.getNextEntry()) {
if (zipEntry.isDirectory()) {
continue;
}
System.out.println(zipEntry.getName());
for (int len = zis.read(buffer); len > 0; len = zis.read(buffer)) {
System.out.write(buffer, 0, len);
}
}
}
}

how to include signature in outlook javamail

I'm trying to create an email using javamail where i can attach many files and also configure the body message , destination and many settings... at the end i save this email in a temp file to use it in outlook 2016 where i can now open outlook and pass the eml file using outlook command line with switch /eml.
The problem is is a try to attach one file with outlook using the switch /a, i can see the signature the footer of the body message but when i use the created eml file i can not see any signature.
what i tried to do is to load the pre-saved signature in roaming folder from different format (htm, rtf and txt) with txt file there is no problem and can put it inside the message in eml file but using rtf i cannot visualize the content as i see in ms word, using the htm file the images (if exist) still not visible.
I'm wondering how i can use one of the two (html or rtf file) to include the signature in the bottom of the body message automatically.
Hope that someone already worked on the same subject.
I think you can take a snapshot of the signature and save it in a particular directory and send a HTML email by inserting the image . You can find something here on how you can send inline HTML images in the message body. Hope it helps.
The problem is mainly in the path's image included in the htm file, so I parsed the original path with the absolute one, so i can visualize the image correctly
public static String getSignature() throws IOException {
String content ="";
String appDataPath = System.getenv("APPDATA")+"\\Microsoft\\Signatures\\";
System.out.println(appDataPath);
File folder = new File(appDataPath);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
File file = listOfFiles[i];
if (file.isFile() && file.getName().endsWith(".htm")) {
content = FileUtils.readFileToString(file , "windows-1252");
content =content.replaceAll("src=\"", "src=\"" +appDataPath.replace("\\", "/"));
}
}
return content;
}
Then I retrieve the content and I put it inside the message that I want to send.
MimeBodyPart body = new MimeBodyPart();
body.setDisposition(MimePart.INLINE);
body.setContent(signature, "text/html");
mmp.addBodyPart(body);
I added some enhancement on the code:
public static String[] getSignature() throws IOException {
String content = "";
String appDataPath =System.getenv("APPDATA") + "\\Microsoft\\Signatures\\";
System.out.println(appDataPath);
File folder = new File(appDataPath);
File[] listOfFiles = folder.listFiles();
String imagePath ="";
for (int i = 0; i < listOfFiles.length; i++) {
File file = listOfFiles[i];
if (file.isFile() && file.getName().endsWith(".htm")) {
content = FileUtils.readFileToString(file, "windows-1252");
content = content.replaceAll("src=\"", "src=\"" + appDataPath.replace("\\", "/"));
}else if(file.isDirectory()){
File[] listOfHtmlFiles = file.listFiles();
for (File f : listOfHtmlFiles) {
if(Files.probeContentType(f.toPath()).contains("image")) {
imagePath = f.getPath();
}
}
}
}
return new String[]{content,imagePath};
}
i this new code i retrieve the signature from html and the image path from html files folders.
Then i created image an image as joint file ( attached to the email)
then i modify src in the signature as follow :
MimeBodyPart imgBP = new MimeBodyPart();
DataSource fds = new FileDataSource(imgPath);
imgBP.setDataHandler(new DataHandler(fds));
imgBP.setHeader("Content-ID", "<image>");
mmp.addBodyPart(imgBP);
signature = signature.replaceFirst("(src=)([\"|\'])(.*)([\"|\'])",
"$1$2cid:image$4");
MimeBodyPart body = new MimeBodyPart();
body.setDisposition(MimePart.INLINE);
body.setContent("<br><br><br>" + signature, "text/html");
mmp.addBodyPart(body);

How to create test data for Java MimeMessage objects with attachments?

I want to persist mails in a database. To test it, I try to generate some test MimeMessage objects with and without attachments. I add the attachments like this:
MimeMessage message = new MimeMessage(Session.getDefaultInstance(props, null));
Multipart multipart = new MimeMultiPart();
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.attachFile("./files/test.txt");
bodyPart.setFileName("test.txt");
multipart.addBodyPart(bodyPart);
message.setContent(multipart);
message.saveChanges();
Now I want to serialize this MimeMessage with its writeTo(OutputStream) method. That call results in a FileNotFoundException:
java.io.FileNotFoundException: ./files/test.txt: open failed: ENOENT (No such file or directory)
It seems like the writeTo()-Method is searching for the attached files. Shouldn't the files already be contained inside the MimeMessage-Object, through the attachFile()-call in my test data generator? Do I have to do something with the MimeMessage-Object to be able to serialize it like that?
Try using a File object, where you can check if that file exists.
private static BodyPart createAttachment(filepath) {
File file = new File(filepath);
if (file.exists()) {
DataSource source = new FileDataSource(file);
DataHandler handler = new DataHandler(source);
BodyPart attachment = new MimeBodyPart();
attachment.setDataHandler(handler);
attachment.setFileName(file.getName());
return attachment;
}
return null; // or throw exception
}
I noticed that you're providing a relative path to a file (starting with a dot "."). That only works if the file is in the same directory (or a subdirectory in your case) where your application is executing from. Try using an absolute path instead.

Lost reference to File when I rotate a file in Java

I want to know when a file has rotated because because I'm watching a file and I have to get a new file with the content of this file and the new file. I have to use Java6, so I don't have the new features of JDK7.
The problem is that when I rotate the file (keeping a reference to the file), the old reference gets updated, I would like that it'd point to the old file.
I was doing something like this:
if (reader == null) {
reader = new RandomAccessFile(toWatch, "r");
}
System.out.println("LasModified:" + new Date(toWatch.lastModified()));
System.out.println("Cuando se creo to Watch long:" + reader.length()); --> lenght is okay.
//Here, I use logrotate to simulate what it could happen. (I execute the code in debug mode to be able to do it
long len = 0L;
File f = new File("/home/gortiz/logRotate/test.flume");
System.out.println("LasModified NewReader:" + new Date(f.lastModified()));
RandomAccessFile newReader = new RandomAccessFile(toWatch, "r");
len = reader.length(); --> len = 0
long newLength = newReader.length(); --> newLenght = 0
I could check if there's a file with name.1. Usually logs system renames logs like that.. but, it's not a good solution because nobody guarantees that that's going to be as log system renames files or even they could be moved to another directory.

java servlet cos multipart: save inpustream for later storage

I am using COS multipart to handle file upload on the servlet.
When processing the parts i need to rename the file with an extra posted field (ParamPart), in this case 'artikelcode' needs to be prepended to the filename.
So instead of directly writing the FilePart to disk i need to save the inputstream in memory.
This is the code i have so far:
MultipartParser multipartParser = new MultipartParser(request, 100000000);
String artikelcode = null;
String filename = null;
InputStream in = null;
while ((part = multipartParser.readNextPart()) != null) {
if (part.isFile()) {
FilePart filePart = (FilePart) part;
filename = filePart.getFileName();
//long fileSize = filePart.writeTo(new File(fileSavePath));
if (filename != null) in = filePart.getInputStream();
}
if (part.isParam()) {
ParamPart paramPart = (ParamPart) part;
if (paramPart.getName().equals("artikelcode")) artikelcode = paramPart.getStringValue();
}
}
if (in != null)
{
String fileSavePath = "c:\\upload\\"+artikelcode+"_"+filename;
File file = new File(fileSavePath);
OutputStream out = new FileOutputStream(file);
IOUtils.copy(in, out);
out.close();
}
When the file is saved on disk, it is empty!
Thanks for your help!!
Calling readNextPart() invalidates any data that you got from the previous part.
Here is a better approach: Always save the file with a temporary name and then rename it.
This allows you to handle a lot of common errors graciously like: Disk full, errors while saving, etc. because you never overwrite existing files until you are 100% sure the new file is complete.
Try to replace double slash with single slash like this..
String fileSavePath = "c:/upload/"+artikelcode+"_"+filename;

Categories

Resources