When I upload files to local system's temp directory from Mozilla Browser I get Access denied error. But if I do the same thing from Eclipse Browser I dont see any error, means it is uploading without any error:
Code:
for (Part part : request.getParts()) {
fileName = getFileName(part);
part.write(System.getProperty("java.io.tmpdir") + fileName);
}
private String getFileName(Part part) {
String contentDisp = part.getHeader("content-disposition");
System.out.println("content-disposition header= "+contentDisp);
String[] tokens = contentDisp.split(";");
for (String token : tokens) {
if (token.trim().startsWith("filename")) {
return token.substring(token.indexOf("=") + 2, token.length()-1);
}
}
return "";
Error:
java.io.IOException: java.io.FileNotFoundException: C:\Users\user\AppData\Local\Temp (Access is denied)
Allan, this is the code:
final String path = System.getProperty("java.io.tmpdir");
OutputStream out = null;
InputStream filecontent = null;
final PrintWriter writer = response.getWriter();
try {
for (Part part : request.getParts()) {
String fileName = getFileName(part);
out = new FileOutputStream(new File(path , fileName));
filecontent = part.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
File UploadedFile = new File(path + File.separator + fileName);
UploadedFile.delete();
}
} catch (FileNotFoundException fne) {
writer.println("You either did not specify a file to upload or are "
+ "trying to upload a file to a protected or nonexistent "
+ "location.");
} finally {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
if (writer != null) {
writer.close();
}
}
See this example, when create the file use two parameter as the example:
File scratchFile = new File(System.getProperty("java.io.tmpdir"), "filename.tmp");
Example:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// Create path components to save the file
final String path = System.getProperty("java.io.tmpdir");
final Part filePart = request.getPart("file");
final String fileName = getFileName(filePart);
OutputStream out = null;
InputStream filecontent = null;
final PrintWriter writer = response.getWriter();
try {
//File Temp here with two parameters
out = new FileOutputStream(new File(path , "filename.tmp"));
filecontent = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
writer.println("New file " + fileName + " created at " + path);
} catch (FileNotFoundException fne) {
writer.println("You either did not specify a file to upload or are "
+ "trying to upload a file to a protected or nonexistent "
+ "location.");
writer.println("<br/> ERROR: " + fne.getMessage());
} finally {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
if (writer != null) {
writer.close();
}
}
}
And your method:
private String getFileName(final Part part) {
final String partHeader = part.getHeader("content-disposition");
LOGGER.log(Level.INFO, "Part Header = {0}", partHeader);
for (String content : part.getHeader("content-disposition").split(";")) {
if (content.trim().startsWith("filename")) {
return content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
}
}
return null;
}
References:
Permission
Upload Method
In case of a web application, the Webcontainer might have set some SecurityManager (https://docs.oracle.com/javase/8/docs/api/java/lang/SecurityManager.html) to block write access to the local file system.
Check if this has been the case...
Same problem I was facing few minutes ago.
Your code won't work for file upload with other request parameter together.
when you're calling getParts() it takes other parameters also as parts.
Now in case of file taken as part content-dipsosition header has
form-data; name="<file-parameter-name>"; filename="<filename>"
A thing to be noted <filename> may be different if submitted from
different browser. Try to submit it from eclipse's in built browser.
Try to print and see content-disposition header by
System.out.println(part.getHeader("content-disposition"));
In case of your loop runs for other parameters taken as part, content-disposition has
form-data; name=""
Now see there is nothing like filename="", so your function to get filename returns null.
Now you calls part.write() but inside only path is passed not filename as function you called to get filename returns null. So you get exception even thought it actually uploads file.
After getting filename put a condition
if(filename.equals("")){continue;}
But that's also not a good solution as loop iterate for no reason for other parameter.
Related
I have been trying to duplicate a file but change the name of it in the same windows directory but I got not luck.
I cant just copy the file in the same directory because of the windows rule that two files cannot have the same name in the same directory.
I am not allowed to copy it to another directory then rename it, and then move it back in the same directory.
And I don't see any helpful implementation in the File.class.
Tried something like that but it didnt work:
File file = new File(filePath);
File copiedFile = new File(filePath);
//then rename the copiedFile and then try to copy it
Files.copy(file, copiedFile);
An initial attempt would be using Path as suitable:
Path file = Paths.get(filePath);
String name = file.getFileName().toString();
String copiedName = name.replaceFirst("(\\.[^\\.]*)?$", "-copy$0");
Path copiedFile = file.resolveSibling(copiedName);
try {
Files.copy(file, copiedFile);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
You could create a new file in the same directory and then just copy the contents of the original file to the duplicate
See: Java read from one file and write into another file using methods
For more info
you can also use this snippet from https://www.journaldev.com/861/java-copy-file
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
#Pierre his code is perfect, however this is what I use so I won't be able to change the extension:
public static void copyWithDifferentName(File sourceFile, String newFileName) {
if (sourceFile == null || newFileName == null || newFileName.isEmpty()) {
return;
}
String extension = "";
if (sourceFile.getName().split("\\.").length > 1) {
extension = sourceFile.getName().split("\\.")[sourceFile.getName().split("\\.").length - 1];
}
String path = sourceFile.getAbsolutePath();
String newPath = path.substring(0, path.length() - sourceFile.getName().length()) + newFileName;
if (!extension.isEmpty()) {
newPath += "." + extension;
}
try (OutputStream out = new FileOutputStream(newPath)) {
Files.copy(sourceFile.toPath(), out);
} catch (IOException e) {
e.printStackTrace();
}
}
I'm writing a program to download a PDF file from server. I'm using some program given here Download file by passing URL using java code, this solution works fine for the sample URL provided in the first answer, but not for PDF, I'm replacing just the URL. Below is my code.
import java.io.*;
import java.net.*;
public class FileDownloadTest {
final static int size = 1024;
public static void fileUrl(String fAddress, String localFileName, String destinationDir) {
// localFileName = "Hello World";
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
try {
URL url;
byte[] buf;
int byteRead, byteWritten = 0;
url = new URL(fAddress);
outStream = new BufferedOutputStream(new FileOutputStream(destinationDir + "\\" + localFileName));
uCon = url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];
while ((byteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, byteRead);
byteWritten += byteRead;
}
System.out.println("Downloaded Successfully.");
System.out.println("File name:\"" + localFileName + "\"\nNo ofbytes :" + byteWritten);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void fileDownload(String fAddress, String destinationDir) {
int slashIndex = fAddress.lastIndexOf('/');
int periodIndex = fAddress.lastIndexOf('.');
String fileName = fAddress.substring(slashIndex + 1);
if (periodIndex >= 1 && slashIndex >= 0 && slashIndex < fAddress.length() - 1) {
fileUrl(fAddress, fileName, destinationDir);
} else {
System.err.println("path or file name.");
}
}
public static void main(String[] args) {
String fAddress = "http://singztechmusings.files.wordpress.com/2011/09/maven_eclipse_and_osgi_working_together.pdf";
String destinationDir = "D:\\FileDownload";
fileDownload(fAddress, destinationDir);
}
}
Here, This pdf has 73 pages, and in my folder, it is download as a PDF of 1KB, when opened in Acrobat Reader, it says that the file might be corrupted.
I've also tried the code provided here https://dzone.com/articles/java-how-save-download-file, but the result is same.
please let me know how can I fix this.
Thanks
If you check the downloaded file content, you can see it is html. The server is redirecting the original request to https url. Use url https://singztechmusings.files.wordpress.com/2011/09/maven_eclipse_and_osgi_working_together.pdf instead.
Or use http client with automatic redirect handling, ala http-commons
You define a Variable size = 1024 and use this to define your Buffer.
So logically you can only write 1 KB into it.
But if the input Stream reads more at once it will be lost ... So change your Buffer size to a value which would be able to contain most documents or try to determine the necessary size
I'm looking for the best way to save an email body which includes inline images and HTML content. I want to Retain everything the mail contains.
My ultimate Goal is to save the complete email body into a PDF
If there is a direct way to write email body into PDF ?
if not what would be the best format to save the email ?
I can convert HTML, DOC etc to PDF using some other available API.
private void downloadAttachment(Part part, String folderPath) throws Exception {
String disPosition = part.getDisposition();
String fileName = part.getFileName();
String decodedText = null;
logger.info("Disposition type :: " + disPosition);
logger.info("Attached File Name :: " + fileName);
if (disPosition != null && disPosition.equalsIgnoreCase(Part.ATTACHMENT)) {
logger.info("DisPosition is ATTACHMENT type.");
File file = new File(folderPath + File.separator + decodedText);
file.getParentFile().mkdirs();
saveEmailAttachment(file, part);
} else if (fileName != null && disPosition == null) {
logger.info("DisPosition is Null type but file name is valid. Possibly inline attchment");
File file = new File(folderPath + File.separator + decodedText);
file.getParentFile().mkdirs();
saveEmailAttachment(file, part);
} else if (fileName == null && disPosition == null) {
logger.info("DisPosition is Null type but file name is null. It is email body.");
File file = new File(folderPath + File.separator + "mail.html");
file.getParentFile().mkdirs();
saveEmailAttachment(file, part);
}
}
protected int saveEmailAttachment(File saveFile, Part part) throws Exception {
BufferedOutputStream bos = null;
InputStream is = null;
int ret = 0, count = 0;
try {
bos = new BufferedOutputStream(new FileOutputStream(saveFile));
part.writeTo(new FileOutputStream(saveFile));
} finally {
try {
if (bos != null) {
bos.close();
}
if (is != null) {
is.close();
}
} catch (IOException ioe) {
logger.error("Error while closing the stream.", ioe);
}
}
return count;
}
Please suggest. Thank you!
Save it in its natural state, as a MimeMessage.
JavaMail MimeMessages can be streamed to text, since that's how they arrive in mail. For example, MimeMessage.writeTo saves the message out as text. Similarly, MimeMessage.parse reads it back in. One in a MimeMessage, you can get the text, the attachments, etc. quite easily.
You could also stream it out as a serialized Java object, but, frankly, I wouldn't. The text representation is much more useful.
My issue goes as follows:
I have My code setup to read emails from a particular account. That part works perfectly.
the issue is with parsing the Email message. Separating attachments and email body(containing inline images).
My code goes like this:
Void readMessages(Folder folder){
Message[] messages = folder.getMessages();
// loading of message objects.
for (int messageNumber = 0; messageNumber < messages.length; messageNumber++) {
final Message currentMessage = messages[messageNumber];
logger.info("Handling the mail with subject " + currentMessage.getSubject());
logger.info("Content type for the current message is " + currentMessage.getContentType());
final String messageFileName = currentMessage.getFileName();
logger.info("File name for the message " + messageFileName + ". File name is blank "
+ StringUtils.isBlank(messageFileName));
Object messageContentObject = currentMessage.getContent();
if (messageContentObject instanceof Multipart) {
Multipart multipart = (Multipart) messageContentObject;
// downloading all attachments....
int attachmentCount = multipart.getCount();
logger.info("Number of attachments ");
for (int i = 0; i < attachmentCount; i++) {
Part part = (Part) multipart.getBodyPart(i);
downloadAttachment(part, folderPath.toString());
}
}
}
}
}
private void downloadAttachment(Part part, String folderPath) throws Exception {
String disPosition = part.getDisposition();
String fileName = part.getFileName();
String decodedText = null;
logger.info("Disposition type :: " + disPosition);
logger.info("Attached File Name :: " + fileName);
if (disPosition != null && disPosition.equalsIgnoreCase(Part.ATTACHMENT)) {
logger.info("DisPosition is ATTACHMENT type.");
File file = new File(folderPath + File.separator + decodedText);
file.getParentFile().mkdirs();
saveEmailAttachment(file, part);
} else if (fileName != null && disPosition == null) {
logger.info("DisPosition is Null type but file name is valid. Possibly inline attchment");
File file = new File(folderPath + File.separator + decodedText);
file.getParentFile().mkdirs();
saveEmailAttachment(file, part);
} else if (fileName == null && disPosition == null) {
logger.info("DisPosition is Null type but file name is null. It is email body.");
File file = new File(folderPath + File.separator + "mail.html");
file.getParentFile().mkdirs();
saveEmailAttachment(file, part);
}
}
protected int saveEmailAttachment(File saveFile, Part part) throws Exception {
BufferedOutputStream bos = null;
InputStream is = null;
int ret = 0, count = 0;
try {
bos = new BufferedOutputStream(new FileOutputStream(saveFile));
part.writeTo(new FileOutputStream(saveFile));
} finally {
try {
if (bos != null) {
bos.close();
}
if (is != null) {
is.close();
}
} catch (IOException ioe) {
logger.error("Error while closing the stream.", ioe);
}
}
return count;
}
The problem i get is when i run this code, i get an HTML file but the inline images is replaced by a sign for error image which indicates the image with no source.
Please help me out with. Let me know if any more info is required.
I also tried saving the body as an .eml file by changing:
File file = new File(folderPath + File.separator + "mail.html");
to
File file = new File(folderPath + File.separator + "mail.eml");
BUt i got the same results.
I wrote below code to convert email body text to pdf including inline images.
in code i replaced the image code(ex: cid:image001.jpg#01D17AAA.1EA2A6A0) with download image path. I am constructing the "hashmap" for image key and download path while downloading the image.
HTMLWorker htmlWorker = new HTMLWorker(document);
if(bodyStr!=null)
{
//find inline images
inlineImages=downloadInLineImage(mostRecentMatch, dynamicOutputDirectory);
if(inlineImages!=null)
{
for (Map.Entry<String, String> entry : inlineImages.entrySet()) {
//System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
bodyStr=bodyStr.replaceAll("cid:"+entry.getKey() , entry.getValue());
}
}
htmlWorker.parse(new StringReader(bodyStr));
}
Download Inline image with passing Item.
private HashMap<String,String> downloadInLineImage(Item item, String dynamicOutputDirectory)
throws Exception, ServiceLocalException {
//create output directory if not present
//bind the item to a new email message. if you do not bind, then the getHasAttachments() function will fail
EmailMessage mostRecentMatch = (EmailMessage)item;
String from = mostRecentMatch.getFrom().getAddress();
String user =StringUtils.substringBefore(from, "#");
AttachmentCollection collection=item.getAttachments();
HashMap<String,String> inlineFiles=new HashMap<String,String>();
if(collection.getCount()>0)
{
for (Attachment attachment : collection.getItems()) {
if(attachment.getIsInline())
{
FileAttachment currentFile = (FileAttachment) attachment;
String filePath=dynamicOutputDirectory+"/"+user+currentFile.getName();
File file=new File(filePath);
FileOutputStream fio=new FileOutputStream(file);
currentFile.load(fio);
inlineFiles.put(currentFile.getContentId(), filePath);
fio.close();
}
}
}
References to inlined images are replaced by cid: URNs like <img src="cid:SOMEID">, because there are no filenames in an email. SOMEID refers to the Content-ID of the Multipart "objects".
In order to get it work, you have to store the multipart attachments to files (e.g., temporary names) and replace the cid URNs by the real file names.
I am having a zip file into my project. When I am running my code through IDE, my extract(String file, String destination) method works fine.
D:/Tools/JAVA/Lodable_Creation/build/classes/ib2.zip-->
String s1=getClass().getResource("Test.zip").getPath().toString();
extract(s1, "c:\\");
This is giving me Path s1 is--> D:\Tools\JAVA\Lodable_Creation\build
When I compile same code and run through Command prompt
file:/D:/Tools/JAVA/Lodable_Creation/dist/Lodable_Creation.jar!/Test.zip
s1 is-->D:\Tools\JAVA\Lodable_Creation\dist
And I am not getting output. Please help me.
UPDATE:-
public static void extract(String file, String destination) throws IOException {
ZipInputStream in = null;
OutputStream out = null;
try {
// Open the ZIP file
in = new ZipInputStream(new FileInputStream(file));
// Get the first entry
ZipEntry entry = null;
while ((entry = in.getNextEntry()) != null) {
String outFilename = entry.getName();
// Open the output file
if (entry.isDirectory()) {
new File(destination, outFilename).mkdirs();
} else {
out = new FileOutputStream(new File(destination,outFilename));
// Transfer bytes from the ZIP file to the output file
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
}
}
} finally {
// Close the stream
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
On Ok Click button
Map map = System.getenv();
Set keys = map.keySet();
String newString = (String) map.get("CYGWIN_HOME");
System.out.println(" " + newString);
String destination= newString.replace(";", "");
System.out.println(" " + destination);
String S =getClass().getResource("Test.zip").getPath().toString();
File jarFile = new File(S);
String file=jarFile.toString();
extract(file,destination);
This is my actual code for extract method and on OK Button. This is extracting Test.zip file to the Destination folder. i.e CYGWIN_HOME
If your file path is actually a URL (starts with "file://") then use new ZipInputStream((new URL(file)).openStream()) otherwise use new ZipInputStream(new FileInputStream(file)) like you already do.