Uploading a file in Java Servlet - java

I have a Java Dynamic Web Project, and I'm using TomCat v7.0.
I am new to web projects and I didn't quite understand how I can upload a file in one of my jsp pages. Since my project is intended to be only local, I thought I could use a multipart form in which the person would choose the file (and this part goes fine) and later retreive the file path from my Servlet. I can't complete this part though, it appears to only give me the name of the file, not its entire path.
Can anyone point me to the right direction? I've read several posts about Apache File Upload and retreiving information from the multipart form but nothing seems to help me.
How can I get the file path from a form or alternatively how can I get the uploaded file to use in my Java classes?
Thanks in advance.
.jsp:
<form method="post" action="upload" enctype="multipart/form-data">
<input type="file" name="filePath" accept="application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"></input>
<input type="submit" value="Enviar"></input>
</form>
Java Servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
PrintWriter out = response.getWriter();
out.println("<html><body>");
try
{
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : items)
{
if (item.isFormField())
{
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
String fieldname = item.getFieldName();
String fieldvalue = item.getString();
out.println("<h1>"+fieldname+" / "+fieldvalue+"</h1>");
}
else
{
// Process form file field (input type="file").
String fieldname = item.getFieldName();
String filename = item.getName();
InputStream filecontent = item.getInputStream();
String s = filecontent.toString();
out.println("<h1>"+s+" / "+filename+"</h1>");
item.write(null);
}
}
}
catch (FileUploadException e)
{
throw new ServletException("Cannot parse multipart request.", e);
}
catch (Exception e)
{
e.printStackTrace();
}
out.println("</body></html>");
}

Not providing the file path is a security feature of the browser.
You have the file contents available in your code (InputStream filecontent) so you could use that or use one of the convenience methods on FileItem, e.g.
item.write(new File("/path/to/myfile.txt"));

Related

Jsp loading image from webapps ROOT folder

I am working on a Java application and what I want to do is to give to the users the functionality to upload an image and view it at their profile. I know similar questions have been answered many many times but this is my first time doing this and I am really struggling to make it work.
So this is my testing code:
upload.jsp
...
<body>
<form method="post" action="FileUploader" encType="multipart/form-data">
<input type="file" name="file" value="select images..."/>
<input type="submit" value="start upload"/>
</form>
</body>
...
FileUploader.java
As you can see here, I store all my images in Tomcat's webapps/ROOT/files folder.
#WebServlet("/FileUploader")
public class FileUploader extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
if(!ServletFileUpload.isMultipartContent(request)){
out.println("Nothing to upload");
return;
}
FileItemFactory itemfactory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(itemfactory);
try{
List<FileItem> items = upload.parseRequest(new ServletRequestContext(request));
for(FileItem item:items){
String contentType = item.getContentType();
if(!contentType.equals("image/png")){
out.println("only png format image files supported");
continue;
}
File uploadDir = new File("/home/agg/apache-tomcat/webapps/ROOT/files");
File file = File.createTempFile("img",".png",uploadDir);
item.write(file);
out.println("Filename: " + file.getName());
out.println("File Saved Successfully");
response.sendRedirect("message.jsp");
}
}
catch(FileUploadException e){
out.println("upload fail");
}
catch(Exception ex){
out.println("can't save");
}
}
}
message.jsp
Here, I am trying to load one of the images saved through another servlet.
...
<body>
<img src="file/img1.png">
</body>
FileServlet.java
Servlet that retrieves the image.
#WebServlet("/file/*")
public class FileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
private String filePath;
public void init() throws ServletException {
this.filePath = "/files";
}
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================In do get==================");
// Get requested file by path info.
String requestedFile = request.getPathInfo();
System.out.println("Requested File: " + requestedFile);
// Check if file is actually supplied to the request URI.
if (requestedFile == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// Decode the file name (might contain spaces and on) and prepare file object.
File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));
System.out.println("Filename: " + file.getName());
System.out.println(file.getAbsolutePath());
// Check if file actually exists in filesystem.
if (!file.exists()) {
System.out.println("DOES NOT EXIST");
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// more code here but it does not matter
}
}
The problem is that the image does not load. The path printed at the console seems to be correct. What am I missing here?
For me your problem is here
<img src="file/img1.png">
It doesn't seem to be the correct path for the next reasons:
The root directory is /.../webapps/ROOT/files so it should start with files not file.
The name of the file should be img + a random long + .png here you set the random long to 1 which doesn't seem to be correct
As it is in the ROOT webapp, you should rather put an absolute path instead of a relative path, in other words the path should start with a slash

Retrieve file from POST request with NanoHttpd

I am trying to use the NanoHttpd library to upload files to my Android server by using a POST request from a form. I do receive the POST request on the server side. My question is how to retrieve the file from the POST request so I can save it somewhere in the device memory.
the form :
<form action='?' method='post' enctype='multipart/form-data'>
<input type='file' name='file' />`enter code here`
<input type='submit'name='submit' value='Upload'/>
</form>
the serve method :
#Override
public Response serve (IHTTPSession session) {
Method method = session.getMethod();
String uri = session.getUri();
if (Method.POST.equals(method)) {
//get file from POST and save it in the device memory
}
...
}
Last night i found solution it's very easy to upload file....
First you have manage 'TempFileManager'. It's handle temp file directory so it' create file and delete automatically after your work finish like copy,read,edit,move etc...
server.setTempFileManagerFactory(new ExampleManagerFactory());
So now you not have manage temp file it's work automatically...
Manage post request like this
private Response POST(IHTTPSession) {
try {
Map<String, String> files = new HashMap<String, String>();
session.parseBody(files);
Set<String> keys = files.keySet();
for(String key: keys){
String name = key;
String loaction = files.get(key);
File tempfile = new File(loaction);
Files.copy(tempfile.toPath(), new File("destinamtio_path"+name).toPath(), StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException | ResponseException e) {
System.out.println("i am error file upload post ");
e.printStackTrace();
}
return createResponse(Status.OK, NanoHTTPD.MIME_PLAINTEXT, "ok i am ");
}

Java Servlets Using MultipartConfig

I am using a catch-all servlet and passing the request object along to other internal framework classes. Its how my application is designed. The reasons are beyond the scope of this question.
#WebServlet(name="RequestHandler", urlPatterns="/*")
I am trying to do file uploading from the browser using multipart-form-data:
<form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" name="videoUpload" value="Upload"/>
</form>
And the only way to actually pass the file data along to the server is to annotate the servlet with:
#MultipartConfig
If I annotate my catch-all servlet, everything works fine but its not very often at all that I actually need to use the file uploading functionality.
Option 1: Leave it alone.
Does leaving the annotation cause unnecessary overhead even though most of the requests don't use it?
Option 2: Add it programatically?
Is there a way to programatically add the annotation if the form type of multipart is detected?
Option 3: Use the annotation elsewhere.
What about using the annotation in a separate class (i'm assuming it needs to be present before the request object is actually created...)?
It is ok if you dont add '#MultipartConfig' annotation. You can determine programmatically if the content is multipart or not:
String form_field="";
FileItem fileItem = null;
if (ServletFileUpload.isMultipartContent(request)) {
ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory());
try {
fileItemsList = servletFileUpload.parseRequest(request);
} catch (FileUploadException ex) {
out.print(ex);
}
String optionalFileName = "";
Iterator it = fileItemsList.iterator();
while (it.hasNext()) {
FileItem fileItemTemp = (FileItem) it.next();
if (fileItemTemp.isFormField()) {
if (fileItemTemp.getFieldName().equals("form_field")) {
form_field = fileItemTemp.getString();
}
} else {
if (fileItemTemp.getFieldName().equals("file")) {
fileItem = fileItemTemp;
}
}
}
}
If ServletFileUpload.isMultipartContent(request) is false then you can retrieve form parameters in general way by request.getParameter. I have used apache file upload in the example.

file upload with spring MVC

I am uploading file using spring MVC and jquery. Inside my class method I have written
#RequestMapping(value="attachFile", method=RequestMethod.POST)
public #ResponseBody List<FileAttachment> upload(
#RequestParam("file") MultipartFile file,
HttpServletRequest request,
HttpSession session) {
String fileName = null;
InputStream inputStream = null;
OutputStream outputStream = null;
//Save the file to a temporary location
ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath("/");
fileName = realContextPath +"/images/"+file.getOriginalFilename();
//File dest = new File(fileName);
try {
//file.transferTo(dest);
inputStream = file.getInputStream();
outputStream = new FileOutputStream(fileName);
inputStream.close();
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Its uploading the file correctly I am using
ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath("/");
to get the path. My first question is , Is this the correct way to get the path and it stores the file somewhere at
workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/images
and when I am trying to display this image on my jsp page using the following code
<img src="<%=request.getRealPath("/") + "images/images.jpg" %>" alt="Upload Image" />
It does not display the image, Its generating the following html
<img src="/home/name/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/images/images.jpg" alt="Upload Image">
Am I doing the things right? In my project I have to upload large number of files everyday.
Please let me know if you need anything else to understand my question
It will be better if you upload your files in some directory by absolute path(e.g. C:\images\) instead of relative (your approach). Usually, web apps runs on linux mathines on production and it is good practice to make save path configurable.
Create some application property which will holds save path for files(in xml or property file).

How to submit a form with an image file using java? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to upload a file using Java HttpClient library working with PHP - strange problem
I'm trying to create a script that can automatically submit a form on a website with two fields: title and description and a file input where I should upload an image.
The last days I've searched every page I found on google but I can't solve my problem...
I also need to post a cookie, I've made the cookie using:
connection.setRequestProperty("Cookie", cookie); //this worked
But I have problems submitting the form, first I'we tried using HttpUrlConnection, but I was unable to figure it out, now I'm trying to solve my problem using HttpClient
The html form looks like this:
<form action="submit.php" method="post" enctype="multipart/form-data">
<input type="text" name="title">
<input name="biguploadimage" type="file">
<textarea name="description"></textarea>
<input type="image" src="/images/submit-button.png">
</form>
My image is located at d:/images/x.gif
Please provide me a full code because I'm new to java.
O, and how to create the cookie using HttpClient ?
Thanks a lot in advice!
This url might help you to solve your problem. It's not that straightforward otherwise I would have pasted the code here. upload files in java
You could also look at this question here
similar question on stackoverflow
There is good article with code examples: http://www.theserverside.com/news/1365153/HttpClient-and-FileUpload
Pay attention to MultipartPostMethod. This will allow you to post file and another data in one request.
How to do simple POST with many parameters described there: http://hc.apache.org/httpclient-3.x/methods/post.html
I recently did this using Spring Web MVC and Apache Commons FileUpload:
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
(...)
#RequestMapping(method = RequestMethod.POST)
public ModelAndView uploadFile(HttpServletRequest request, HttpServletResponse response) {
ModelAndView modelAndView = new ModelAndView("view");
if (ServletFileUpload.isMultipartContent(request)) {
handleMultiPartContent(request);
}
return modelAndView;
}
private void handleMultiPartContent(HttpServletRequest request) {
ServletFileUpload upload = new ServletFileUpload();
upload.setFileSizeMax(2097152); // 2 Mb
try {
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
if (!item.isFormField()) {
File tempFile = saveFile(item);
// process the file
}
}
}
catch (FileUploadException e) {
LOG.debug("Error uploading file", e);
}
catch (IOException e) {
LOG.debug("Error uploading file", e);
}
}
private File saveFile(FileItemStream item) {
InputStream in = null;
OutputStream out = null;
try {
in = item.openStream();
File tmpFile = File.createTempFile("tmp_upload", null);
tmpFile.deleteOnExit();
out = new FileOutputStream(tmpFile);
long bytes = 0;
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
bytes += len;
}
LOG.debug(String.format("Saved %s bytes to %s ", bytes, tmpFile.getCanonicalPath()));
return tmpFile;
}
catch (IOException e) {
LOG.debug("Could not save file", e);
Throwable cause = e.getCause();
if (cause instanceof FileSizeLimitExceededException) {
LOG.debug("File too large", e);
}
else {
LOG.debug("Technical error", e);
}
return null;
}
finally {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
catch (IOException e) {
LOG.debug("Could not close stream", e);
}
}
}
This saves the uploaded file to a temp file.
If you don't need all the low-level control over the upload, it is much simpler to use the CommonsMultipartResolver:
<!-- Configure the multipart resolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="2097152"/>
</bean>
An example form in the jsp:
<form:form modelAttribute="myForm" method="post" enctype="multipart/form-data">
<form:input path="bean.uploadedFile" type="file"/>
</form>
The uploadedDocument in the bean is of the type org.springframework.web.multipart.CommonsMultipartFile and can be accessed direcly in the controller (the multipartResolver automatically parses every multipart-request)

Categories