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

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.

Related

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);

File Download Java without Temporary file

I am trying to create a file and send as a response so that file can be downloaded. I am not sure how to do it. My current code
String fileName = "fileToBeSaved.csv";
File file = new File(fileName);
FileWriter writer = new FileWriter(file);
writer.append(data);
writer.flush();
writer.close();
Response.ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition","attachment; filename=\"fileName.csv\"");
return response.build();
This code creates a temporary file on my system. And when the browser receives the response it gets the path to file, like "C:/folderName/FileName"...Upon mentioning this path on the browser, I get the option to download the file.
What I want to achieve is:
I want to create a file (But don't want any temporary file to be created on my system) and send as a response. The browser should receive a prompt asking whether to download the file or not as a response.
Can some one guide me what am I doing wrong?
I finally found the way.
Response.ResponseBuilder response = Response.ok();
response.header("Content-Disposition", "attachment; filename=\"filename.csv\"");
response.entity(contentAsString);
return response.build();
If you cannot build a string out of the contents of the file, then a work-around is:
ByteArrayOutputStream bo = new ByteArrayOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(bo));
//for loop can be any content.. I am just showing a represenatation.
for (int i = 0; i < content.size(); i++) {
writer.write(content.get(i));
}
writer.flush();
Response.ResponseBuilder response = Response.ok();
response.type(MediaType.APPLICATION_OCTET_STREAM);
response.header("Content-Disposition", "attachment");
response.entity(bo.toByteArray());
return response.build();
In the above code, I am building a file and sending to GUI. No temporary file was created.
Hope it helps.
Thanks!

Unable to save the uploaded file into specific directory

I want to upload files and save them into specific directory.And i am new to files concept.When i uploading files from my page they are saved in another directory(C:\Users\ROOTCP~1\AppData\Local\Temp\multipartBody989135345617811478asTemporaryFile) and not in specified directory.I am unable to set it.Please help me in finding a solution.For all help thanks in advance.
public static Result uploadHoFormsByHeadOffice() throws Exception {
Logger.info("#C HoForms -->> uploadHoFormsByHeadOffice() -->> ");
final String basePath = System.getenv("INVOICE_HOME");
play.mvc.Http.MultipartFormData body = request().body()
.asMultipartFormData(); // get Form Body
StringBuffer fileNameString = new StringBuffer(); // to save file path
// in DB
String formType = body.asFormUrlEncoded().get("formType")[0];// get formType from select Box
FilePart upFile = body.getFile("hoFiles");//get the file details
String fileName = upFile.getFilename();//get the file name
String contentType = upFile.getContentType();
File file = upFile.getFile();
//fileName = StringUtils.substringAfterLast(fileName, ".");
// path to Upload Files
File ftemp= new File(basePath +"HeadOfficeForms\\"+formType+"");
//File ftemp = new File(basePath + "//HeadOfficeForms//" + formType);
File f1 = new File(ftemp.getAbsolutePath());// play
ftemp.mkdirs();
file.setWritable(true);
file.setReadable(true);
f1.setWritable(true);
f1.setReadable(true);
//HoForm.create(fileName, new Date(), formType);
Logger.info("#C HoForms -->> uploadHoFormsByHeadOffice() <<-- Redirecting to Upload Page for Head Office");
return redirect(routes.HoForms.showHoFormUploadPage());
}
}
I really confused why the uploaded file is saved in this(C:\Users\ROOTCP~1\AppData\Local\Temp\multipartBody989135345617811478asTemporaryFile) path.
You're almost there.
File file = upFile.getFile(); is the temporary File you're getting through the form input. All you've got to do is move this file to your desired location by doing something like this: file.renameTo(ftemp).
Your problem in your code is that you're creating a bunch of files in memory ftemp and f1, but you never do anything with them (like writing them to the disk).
Also, I recommend you to clean up your code. A lot of it does nothing (aforementioned f1, also the block where you're doing the setWritable's). This will make debugging a lot easier.
I believe when the file is uploaded, it is stored in the system temporary folder as the name you've provided. It's up to you to copy that file to a name and location that you prefer. In your code you are creating the File object f1 which appears to be the location you want the file to end up in.
You need to do a file copy to copy the file from the temporary folder to the folder you want. Probably the easiest way is using the apache commons FileUtils class.
File fileDest = new File(f1, "myDestFileName.txt");
try {
FileUtils.copyFile(ftemp, fileDest);
}
catch(Exception ex) {
...
}

Javamail attachments data lost

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.

Share uploaded file among servlets

Currently, I am having one jsp file, some java beans classes and two servlets.
The first servlet is responsible to upload a file and print out the context of it.
The second servlet is responsible for fetching the java beans code, execute it and print the result on jsp. However this concludes to duplicate code in servlets. Duplicated code is actually that the file need to be re-uploaded in order to call beans:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
Iterator<FileItem> iterator = upload.parseRequest(request).iterator();
File uploadedFile = null;
String dirPath = "C:\\fileuploads";
while (iterator.hasNext()) {
FileItem item = iterator.next();
if (!item.isFormField()) {
String fileNameWithExt = item.getName();
File filePath = new File(dirPath);
if (!filePath.exists()) {
filePath.mkdirs();
}
uploadedFile = new File(dirPath + "/" + fileNameWithExt);
item.write(uploadedFile);
} else {
String otherFieldName = item.getFieldName();
String otherFieldValue = item.getString();
}
}
FileInputStream fstream = new FileInputStream(uploadedFile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
Next there is code which connects the servlet with the java beans. This works but my question is what is the best way to share this uploaded file? If I can store the file path in a variable and call it from the first servlet to second with no duplicated code.
Thanks in advance.
P.S I ve read this question as well, Share uploaded file between servlets in session , but i didnt really manage to do it.
If I can store the file path in a variable and call it from the first servlet to second with no
duplicated code.
So you would be just getting the file path and from second servlet you would be reading file again.
session.setAttribute("filePath",yourCalculatedFilePath);
and retrieve it from different servlet using
session.getAttribute("filePath");
You can just set the filePath in session attribute and you can access it across the session. but putting whole file into session isn't a good idea just imagine a user puts a file of size 1MB and there are 1000 users online at a time (just example) it would cost 1GB of server's memory.

Categories

Resources