I'm interested in having a button which takes a pic from the user's computer and uploads it on my server.
I managed to solve the server uploading part, but I'm having difficulties in handling the path from the user computer. Vaadin Upload does not provide me full path, but I want it to be dynamic. Looking at the documentation, they use some temp location, but I don't know how to implement that.
public OutputStream receiveUpload(String filename,
String mimeType) {
// Create upload stream
FileOutputStream fos = null; // Stream to write to
try {
// Open the file for writing.
file = new File("/tmp/uploads/" + filename);
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
new Notification("Could not open file<br/>",
e.getMessage(),
Notification.Type.ERROR_MESSAGE)
.show(Page.getCurrent());
return null;
}
return fos; // Return the output stream to write to
}
I'm expecting that when the File Chooser closes, I get some kind of file path or handler so I can put it on my server.
In the filename argument you will have the name of uploaded file.
The path of the file however is not sent to the server, this is one of the restrictions of web applications / web browsers.
With the code you use, you will have a copy of the uploaded file on your server in the tmp folder.
There is no way to directly access files on client computers through the web browser.
Related
How to download all files in the file directory when clicking the export or download at the same time?
At present, all the files in the file directory have been obtained, then all the files are placed in the list, and then the stream is written after traversing all the files. However, when importing the second file, it will report cannot reset buffer after response has been committed
The source of the problem is in this code: // response.reset();
Code:
String filePath = "/code/data/";
// Get all file addresses of the directory
List<String> filePathList = getFilePath(filePath);
//Create thread pool
for (String str : filePathList){
download(request, response, str);
}
private void download(HttpServletRequest request,
HttpServletResponse response,String filePath) {
File file = new File(filePath);
//Gets the file name.
String fileName = file.getName();
InputStream fis = null;
try {
fis = new FileInputStream(file);
request.setCharacterEncoding("UTF-8");
String agent = request.getHeader("User-Agent").toUpperCase();
if ((agent.indexOf("MSIE") > 0) || ((agent.indexOf("RV") != - 1) &&
(agent.indexOf("FIREFOX") == -1))) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}
// response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/force-download");
// Set forced download not to open
response.addHeader("Content-Disposition",
"attachment; filename=" + fileName);
response.setHeader("Content-Length", String.valueOf(file.length()));
byte[] b = new byte[1024];
int len;
while ((len = fis.read(b)) != - 1) {
response.getOutputStream().write(b, 0, len);
}
response.flushBuffer();
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
What are the good solutions Thanks
I have not read your code in detail because the bad formatting makes my head hurt.
However, from a superficial reading, it looks like this server-side code is trying to deliver multiple files in response to a single HTTP request.
AFAIK, that is not possible. The HTTP request / response model does not support this. It certainly does not allow a servlet to:
change response headers after the response output stream has been opened
do anything after the response output stream has been closed.
(Your code appears to be trying to do both of those things!)
So, you have to do it differently. Here are some possibilities:
On the server side, assemble all of the files to be downloaded into (say) a temporary ZIP file and then send that. Leave it to the user to unpack the ZIP file ... or not ... as they want.
This is often the best approach. Imagine how annoyed you would be if a few thousand separate files unexpectedly landed in your web browser's Downloads folder.
As 1. and also do something on the client side to transparently unpack the files from the ZIP and put them in the right place in the client's file system.
The "something" could be custom javascript embedded in the web page, or a custom client implemented in Java ... or any other language. (But in the former case, there may be a security issue in allowing sandboxed javascript to write files in arbitrary places without the user confirming each file ... tedious.)
You might be able to send a "multipart" document as the response. However from what I have read, most browsers don't support multipart for downloads; e.g. some browsers will discard all but the last part. (Note: multipart is not designed for this purpose ...)
Change things so that an HTTP request only downloads one file at a time from the directory, and add some client-side stuff to 1) fetch a list of files from the server and iterate the list, fetching each file.
See also: Download multiple files with a single action
I have a problem with saving files and then downloading them after generating a .war file.
I need to handle the generation of many files after pressing the button by admin in the application. The files are generated using part of the code that was sent using the POST method and second part is from the database.
The files are hundreds / thousands and it is impossible to do it manually. Admin generates files from time to time. The user should be able to download these files from the application.
When I run the application in IntelliJ, app has access to the folders on the disk, so the following code works:
(part of backend class, responfible for saving files in path)
private void saveTextToFile(String text, String fileName) {
String filePathAndName = "/static/myFiles/" + fileName+ ".txt";
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource(".").getFile() + filePathAndName );
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file);
PrintWriter printWriter = new PrintWriter(fileWriter);
printWriter.print(text);
printWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
The file was saved in folder:
C:\Users...\myProject\target\classes\static.
(and this is link to generated file in thymeleaf)
<html xmlns:th="http://www.thymeleaf.org">
<a th:href="#{|/myFiles/${thisIsMyFileName}|}">Download file</a>
</html>
Unfortunately, when I generate the .war file and run it, the files are not saved in the application's "resources" folder. As a result, the user cannot download this file via the link generated by thymeleaf.
In general, you do not want to upload anything into your application's files - it opens you to many security problems if someone figures out how to overwrite parts of the application, and in most application servers, it is simply not writable.
A much better approach is to have a designated server folder where you can write things. For example, you could have the following in your configuration:
myapp.base-folder = /any/server/folder/you/want
And then, in the code, you would find that folder as follows:
// env is an #AutoWired private Environment
File baseFolder = new File(env.getProperty("myapp.base-folder"));
I find this better than using a database (as #Stultuske suggested in comments), because databases are great for relations, but mostly overkill for actual files. Files can be accessed externally without firing up the database with minimal hassle, and having them separate keeps your database much easier to backup.
To generate links to the file, simply create a link as you would to any other type of request
<a th:href="#{/file/${fileId}|}">Download file</a>
-- and to handle it in the server, but returning the contents of the file:
#GetMapping(value="/file/{id}")
public StreamingResponseBody getFile(#PathVariable long id) throws IOException {
File f = new File(baseFolder, ""+id); // numerical id prevents filesytem traversal
InputStream in;
if (f.exists()) {
in = new BufferedInputStream(new FileInputStream(f));
} else {
// you could also signal error by returning a 404
in = new BufferedInputStream(getClass().getClassLoader()
.getResourceAsStream("static/img/unknown-id.jpg"));
}
return new StreamingResponseBody() {
#Override
public void writeTo(OutputStream os) throws IOException {
FileCopyUtils.copy(in, os);
}
};
}
I prefer numerical IDs to avoid hassles with path traversal - but you can easily use string filenames instead, and deal with security issues by carefully checking that the canonical path of the requested file starts with the canonical path of your baseFolder
I want to download a .txt file from website and my code works, so I don't get an error and it loads the document, but the document is full of hmtl code, instead of my content.
public static void main(String[] args) {
try {
URL website = new URL("http://www.file-upload.net/download-11700212/document.txt.html");
String filepath = "C://Users//" + System.getProperty("user.name") + "//Desktop//document.txt";
ReadableByteChannel channel = Channels.newChannel(website.openStream());
FileOutputStream stream = new FileOutputStream(filepath);
stream.getChannel().transferFrom(channel, 0, Long.MAX_VALUE);
System.out.println("Download successfull.");
} catch (Exception e) {
System.out.println("Download was not successfull.");
}
}
The download itself works, I got the txt file on my desktop, but the content is wrong and full of html code.
Please help.
Thanks.
The URL you are trying to download from is an HTML page, rather than the document itself. The link on that page you should be trying to download from is...
http://www.file-upload.net/download5.php?valid=451.69031370715&id=11700212&name=document.txt
However, if you wish to guarantee that you're downloading a text file, then you should choose a text file to download directly e.g.
http://humanstxt.org/humans.txt
I have a Python project called Python Webscraper which can read a URL and copy its textual contents to a text file without the HTML.
You'll need to install a package called Beautiful Soup then run the code from the GitHub repo.
I have finished developing a java web app using spring and hibernate. In my app, there's a download function. The function runs well on windows env. But when I deploy and run the app on linux env, using Tomcat as the server, the function return zero byte file. The file type is excel (xls). But the browser returns this as pdf file.
Download Function Failed:
Xls File Path on Linux:
and here is the code:
#RequestMapping("downloadXlsTemplate")
public String downloadTemplate(HttpServletRequest request, HttpServletResponse response) {
try {
String filename = "Template.xls";
File onLinux = new File("/opt/tomcat7/webapps/xls/" + filename);
response.setContentType("application/vnd.ms-excel");
response.addHeader("Content-Disposition", "attachment; filename=" + filename);
response.setContentLength((int) onLinux.length());
InputStream inputStream = new FileInputStream(onLinux);
OutputStream responseOutputStream = response.getOutputStream();
int bytes;
while((bytes = inputStream.read()) != -1) {
responseOutputStream.write(bytes);
}
inputStream.close();
responseOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
I have tried various ways, but none were successful.
I will really appreciate any idea, help, or solution
Regards
Yunus
The problem you are facing is a file permission problem. The file is owned by 'root' and your tomcat runs on other user.
Try to move the files to a shared location where the tomcat user can access it. Try the /tmp location or any other shared location.
If it is permission issue, try using chmod unix command giving required permission on file .
e.g., chmod u+rwx
As a good practice, try to refer the file using relative path (using class path resource) instead of absolute path (so it is environment independent).
I'm coding a Spring MVC project on Eclipse. I'm stuck when coding the upload picture function. The client side using HTML5 API to read and send multipart file to server. The following code was used to save the image to server.
#RequestMapping(method = RequestMethod.POST)
public void processUpload(#RequestParam("pic") MultipartFile file) throws IOException {
// if (!result.hasErrors()) {
FileOutputStream outputStream = null;
String filePath = System.getProperty("java.io.tmpdir") + "/" + file.getOriginalFilename();
try {
outputStream = new FileOutputStream(new File(filePath));
outputStream.write(file.getInputStream().read());
outputStream.close();
} catch (Exception e) {
System.out.println("Error while saving file");
The file sent to server and get proceed but the file name is not original file name but some random string that java generated. I found that file in apache-tomcat-6.0.26\work\Catalina\localhost\ with name like this: upload__f20d9c4_1357767c999__7ffe_00000001. The file then disappear.
My question is where the file gone and how to correctly write uploaded file to some folder such as /uploads rather than save to temp folder?
I'm new hear so please correct me if I posted wrong :D
This might help :-
Change the file type to CommonsMultipartFile when you are fetching the file MultipartFile.
file.transferTo(new File("D:/"));
Let me know if this helps.
This may help as well :- http://www.codejava.net/frameworks/spring/spring-mvc-file-upload-tutorial-with-eclipse-ide