Saving an uploaded image remotely - Java and Tomcat - java

These are days that I'm banging my head on this problem and maybe you that certainly know more than me you can help me ....
Then I try to explain better.
I have a javascript file that through the library d3.js builds the html code pages and replaces it with the other code each part a different function ... The page will not charge (Ajax).
At some point I need to allow the user to upload an image to their profile picture so I make sure that the html code bait
<input type="file" id="file">
and a
<input type = "button" onclick = "javaScript: performAjaxSubmit ()">
PerformAjaxSubmit function () sends the data to a Java Servlet via a xmlHttpRequest level 2, which, from what I understand, can send not only strings but also more complex things such as files.
The function is as follows:
function performAjaxSubmit() {
var sampleFile = document.getElementById("file").files[0];
var formdata = new FormData();
formdata.append("sampleFile", sampleFile);
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:8080/Prova/Upload", true);
xhr.send(formdata);
xhr.onload = function(e) {
if (this.status == 200) {
alert(this.responseText);
}
};
}
The code in the Servlet instead is this:
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// Check that we have a file upload request
System.out.println(request.getAttribute("username"));
isMultipart = ServletFileUpload.isMultipartContent(request);
response.setContentType("text/html");
java.io.PrintWriter out = response.getWriter( );
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("C:/Users/Marty/workspaceJEE/Prova/WebContent/imm/utenti"));
filePath="C:/Users/Marty/workspaceJEE/Prova/WebContent/imm/utenti";
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax( maxFileSize );
try{
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator i = fileItems.iterator();
while ( i.hasNext () )
{
FileItem fi = (FileItem)i.next();
if ( !fi.isFormField () )
{
// Get the uploaded file parameters
String fieldName = fi.getFieldName();
String fileName = fi.getName();
String contentType = fi.getContentType();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// Write the file
if( fileName.lastIndexOf("\\") >= 0 ){
file = new File( filePath +"/"+
fileName.substring( fileName.lastIndexOf("\\"))) ;
}else{
System.out.println(filePath +
fileName.substring(fileName.lastIndexOf("\\")+1));
file = new File( filePath +"/"+
fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
}
}
}catch(Exception ex) {
System.out.println(ex);
}
}
Now (sorry if the question is a bit long) it works but the problem is that the images are saved in the path that I have provided me with the command:
factory.setRepository(new File("C:/Users/Marty/workspaceJEE/Prova/WebContent/imm/utenti"));
How do I then save it remotely? That is, once I load the site of such Altrevista, how do I make sure that they are not piĆ  saved to C but in a folder in your project?
I hope I explained. I'm using Apache Tomcat v7.0.
Thanks in advance!

You can use ServletContext.getRealPath
This code returns <context root>/upload (depends on your deployment configuration)
request.getSession().getServletContext().getRealPath("/upload")

Related

avoid duplication while uploading file on server [duplicate]

This question already has answers here:
Recommended way to save uploaded files in a servlet application
(2 answers)
Closed 6 years ago.
I want to avoid duplication while uploading file. If a file is updated then eventhough it has same name as which was uploaded previously, I should be able to upload that file on server.
I have written following servlet:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (req.getParameter("from").equals("upload")) {
// checks if the request actually contains upload file
if (!ServletFileUpload.isMultipartContent(req)) {
PrintWriter writer = resp.getWriter();
writer.println("Request does not contain upload data");
writer.flush();
return;
}
// configures upload settings
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
// constructs the directory path to store upload file
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY;
// creates the directory if it does not exist
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
try {
// parses the request's content to extract file data
List formItems = upload.parseRequest(req);
Iterator iter = formItems.iterator();
// iterates over form's fields
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
// processes only fields that are not form fields
if (!item.isFormField()) {
String fileName = new File(item.getName()).getName();
filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:sss");
System.out.println(f.format(storeFile.lastModified()));
System.out.println(storeFile.lastModified());
System.out.println(f.parse(f.format(storeFile.lastModified())));
File[] files = new File(
"C:\\bootcamp\\programs\\eclipse-jee-neon-RC3-win32-x86_64\\eclipse\\workspace\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\excelFileManagement\\upload")
.listFiles();
int uploadFiles=0;
for (File file : files) {
if (fileName.equals(file.getName())) {
uploadFiles =1;
System.out.println("same");
DateFormat df = new SimpleDateFormat("yyyy-mm-dd hh:mm:sss");
String currentFile = df.format(storeFile.lastModified());
String storedFile = df.format(file.lastModified());
System.out.println("currentFile" + currentFile + "storedFile" + storedFile);
if (currentFile.contains(storedFile)) {
System.out.println("Same file cannot be uploaded again");
getServletContext().getRequestDispatcher("/Error.jsp").forward(req, resp);
} else {
// saves the file on disk
item.write(storeFile);
System.out.println("Upload has been done successfully!");
// Reading excel file
ReadingExcelFile rd = new ReadingExcelFile();
rd.readExcel(filePath);
getServletC
ontext().getRequestDispatcher("/DisplayTables.jsp").forward(req, resp);
}
}
}
catch (Exception ex) {
System.out.println("There was an error: " + ex.getMessage());
}}
However, I am getting same last modified date and time for both the files. And if a new file is uploaded storeFile.lastModified() returns Thu Jan 01 05:30:00 IST 1970 value
Can you confirm what is actual lastModified date of the file already uploaded by OS explorer ?
Second thing in SimpleDateFormat constructor arg m stands for minutes and M stands for month.Also S stands for millsecond.So your correct code would be
SimpleDateFormat("yyyy-MM-dd hh:mm:S")
Can you try with these changes and check ?

How to limit uploaded file size in java servlet

I need to upload an image from client to server using html type='file' which works fine,so far I could is to send file from client and receive on my servlet, but now I need to limit the image size in my servlet upto 2MB and if it's bigger than 2MB I need to send an error to client saying about the image size.
Here my servlet code that I receive sent image:
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
MultipartRequest multipartRequest = new MultipartRequest(request, "D:\\");
out.print("Successfully Uploaded");
}
so far it does is to receive image and save it in D: directory, and I don't want to first save the image and then check image size, but to say something to MultipartRequest that if you received higher than 2MB send an error.
Thanks in advance:)
Since you haven't specified what is "MultipartRequest" class, I assume you are using oreilly package.
It has a public MultipartRequest(HttpServletRequest request, String saveDirectory, int maxPostSize) throws IOException constructor, which takes max file size parameter.
If the uploaded file size is more than maxPostSize, it will throw an IOException. You could probably catch this exception and return error response.
You can restrict the size of the uploaded file when creating a MultipartRequest instance.
MultipartRequest(javax.servlet.http.HttpServletRequest request, java.lang.String saveDirectory)
Constructs a new MultipartRequest to handle the specified request, saving any uploaded files to the given directory, and limiting the upload size to 1 Megabyte.
MultipartRequest(javax.servlet.http.HttpServletRequest request, java.lang.String saveDirectory, int maxPostSize)
Constructs a new MultipartRequest to handle the specified request, saving any uploaded files to the given directory, and limiting the upload size to the specified length.
Use this code on servlet and try it now
private boolean isMultipart;
private String filePath;
private int maxFileSize = 50 * 1024;
private int maxMemSize = 4 * 1024;
private File file ; `
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("c:\\temp"));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax( maxFileSize );
try {
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator i = fileItems.iterator();
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet upload</title>");
out.println("</head>");
out.println("<body>");
while ( i.hasNext () ) {
FileItem fi = (FileItem)i.next();
if ( !fi.isFormField () ) {
// Get the uploaded file parameters
String fieldName = fi.getFieldName();
String fileName = fi.getName();
String contentType = fi.getContentType();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// Write the file
if( fileName.lastIndexOf("\\") >= 0 ) {
file = new File( filePath + fileName.substring( fileName.lastIndexOf("\\"))) ;
} else {
file = new File( filePath + fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
out.println("Uploaded Filename: " + fileName + "<br>");
}
}
out.println("</body>");
out.println("</html>");
} catch(Exception ex) {
System.out.println(ex);
}
file size is in bytes form so u can add max file size according to your requirements bytes to mb thanks

Unable to get the value of form fields when using enctype=multipart/form-data : java servlets

I have written this to upload an image in the specified folder and store the path in database, but when i click on add a blank page is displayed, I have already created all the folders in webcontent.I am using tomcat server:
My upload.jsp code looks something like this:
<form action="Add" method=post enctype="multipart/form-data">
<p>Book name: <input type="text" name="bname" required/></p>
<p>Price:<input type="text" name="bprice" required/></p>
<p>Quantity:<input type="text" name="bqty" required/></p>
<p>Image: <input type="file" name="file" required/></p>
<p>Course: <select name="course">
<option>course 1</option>
<option>course 2</option> <!-- Some more options-->
<input type="submit" value="Add" name="Submit"/></p>
</form>
The Add.java servlet code is:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out=response.getWriter();
String bname=request.getParameter("bname");
String bprice=request.getParameter("bprice");
String bqty=request.getParameter("bqty");
String path="images";
String file=request.getParameter("file");
String course=request.getParameter("course");
if(course.equals("course 1"))
{
path="images/folder1";
}
else if(course.equals("course 2"))
{
path="images/folder2";
}
else
{
path="images";
}
MultipartRequest m=new MultipartRequest(request,path);
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("",user,pass);
PreparedStatement ps=con.prepareStatement("insert into product(bname,course,price,qty,path) values (?,?,?,?,?)");
ps.setString(1,bname);
ps.setString(2,course);
ps.setString(3,bprice);
ps.setString(4,bqty);
ps.setString(5,path+file);
ps.executeUpdate();
}
catch(Exception e)
{
e.printStackTrace();
}
out.print("<p>Product added!</p>");
RequestDispatcher rd=request.getRequestDispatcher("upload.jsp");
rd.include(request, response);
}
I get NullPointer exception.
I read somewhere that instead of using
request.getParameter()
I shoud use
m.getParameter()
I did that and it worked, But that won't solve my problem because my code determines the path based on the value of course from the form.
And also I need to get the filename of the file uploaded, right now I am doing this like this:
String file=request.getParameter("file");
I was trying some sample code and when I used m.getParameter() I managed to get values of all fields except file(I want that coz i want to store the img path in the DB).
When I don't use enctype=multipart/form-data everything works fine (I also get the filename) except the error that content is multipart(That's obvious I know).
ServletRequest#getParameter works only for application/x-www-form-urlencoded data (this encoding is used by default if you don't specify enctype attribute on your form). You can read more information about form content types here.
From the line
MultipartRequest m=new MultipartRequest(request,path);
I am assuming you are using the com.oreilly.servlet library.
In this case, using MultipartRequest#getParameter is a correct way to get the values of fields. In order to get the name of the uploaded file, you can use MultipartRequest#getFilesystemName.
my code determines the path based on the value of course from the form
I am afraid that you won't be able to do this in a clear way with com.oreilly.servlet library. What you could do is move the file by yourself like this:
m.getFile("file").renameTo(new File("newPath"));
Alternatively, you can consider using some other library for dealing with multipart data, such as Apache Commons FileUpload.
You can get both the form fields and the file using cos-multipart.jar.
The following worked for me:
public class FileUploadHandler extends HttpServlet {
private final String UPLOAD_DIRECTORY = "/home/mario/Downloads";
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//fix max file size 500 Mb
int maxFileSize = 500000 * 1024;
int maxMemSize = maxFileSize;
//getting form fields (both text as well as file) (enctype=multipart/form-data)
MultipartRequest mreq = new MultipartRequest(request, UPLOAD_DIRECTORY, maxFileSize);
String uname = mreq.getParameter("username"); //give 'id' in html accordingly
String dateofupload = mreq.getParameter("uploaddate");
//System.out.println(uname);
String NEW_UPLOAD_DIRECTORY = UPLOAD_DIRECTORY;
//get actual file name here //name field in html tag has to be given accordingly
String uploadedfilename = mreq.getFilesystemName("file");
//renaming & moving the file to new location
File newfileloc = new File(NEW_UPLOAD_DIRECTORY + "/" + uploadedfilename);
Boolean uploadresult = mreq.getFile("file").renameTo(newfileloc); //true if success
}
}
This initially saves the file to a location and rename/move it to new location. I could have saved it at the desired location but to do that I need file name, which comes only with the servlet request. But to access filename we need to create 'Multipart' request object. I tried to create two such things, one to access fields and the other to save file. But, cos-multipart.jar has some bugs in handling this.
You might want to consider using Apache commons FileUpload. It helps you handle these kinds of scenarios and handles most of the business logic for you.
When using Apache Commons FileUpload you can parse the request like this:
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Configure a repository (to ensure a secure temp location is used)
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List<FileItem> items = upload.parseRequest(request);
You can parse all the individual
// Process the uploaded items
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}
try this way:
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(MEMORY_THRESHOLD);
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(MAX_FILE_SIZE);
upload.setSizeMax(MAX_REQUEST_SIZE); // sets maximum size of request (include file + form data)
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY;
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
List<FileItem> formItems = upload.parseRequest(request);
if (formItems != null && formItems.size() > 0) {
for (FileItem item : formItems) {
if (!item.isFormField()) {
//file field
} else {
other form field
}

Common File Upload not working

Following is my complete code for uploading file to server using apache common upload. When I test this function in new project, it works. But when I integrated into my project, it's not working anymore. I found the problem in "List fileItems = upload.parseRequest(request);" fileItems there is zero while it should be 1. Is there some wat that I can solve this issue?
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {
// Check that we have a file upload request
//isMultipart = ServletFileUpload.isMultipartContent(request);
response.setContentType("text/html");
java.io.PrintWriter out = response.getWriter( );
if( !isMultipart ){
out.println("<html>");
out.println("<head>")y
out.println("<title>Servlet upload</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>No file uploaded</p>");
out.println("</body>");
out.println("</html>");
return;
}
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("c:\\temp"));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax( maxFileSize );
try{
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator i = fileItems.iterator();
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet upload</title>");
out.println("</head>");
out.println("<body>");
while ( i.hasNext () )
{
FileItem fi = (FileItem)i.next();
if ( !fi.isFormField () )
{
// Get the uploaded file parameters
String fieldName = fi.getFieldName();
String fileName = fi.getName();
String contentType = fi.getContentType();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// Write the file
if( fileName.lastIndexOf("\\") >= 0 ){
file = new File( filePath +
fileName.substring( fileName.lastIndexOf("\\"))) ;
}else{
file = new File( filePath +
fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
out.println("Uploaded Filename: " + fileName + "<br>");
}
}
out.println("</body>");
out.println("</html>");
}catch(Exception ex) {
System.out.println(ex);
}
}
When I test this function in new project, it works. But when I integrated into my project, it's not working anymore.
That's generally a sign that the library versions are different. If you're using maven, compare the dependency graphs below the apache common artifact so you can get your test project on the same version.

Commons File Upload Not Working In Servlet

I have a servlet which is meant to handle the upload of a very large file. I am trying to use commons fileupload to handle it. Currently, the file I am attempting to upload is 287MB.
I set up the FileItemFactory and ServletFileUpload, then set a very large max file size on the ServletFileUpload.
Unfortunately, when I attempt to create a FileItemIterator, nothing happens. The form is set with the correct action, multipart encoding, and for the POST method.
Can anyone assist? doPost() of the servlet is posted below:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// ensure that the form is multipart encoded since we are uploading a file
if (!ServletFileUpload.isMultipartContent(req)) {
//throw new FileUploadException("Request was not multipart");
log.debug("Request was not multipart. Returning from call");
}
// create a list to hold all of the files
List<File> fileList = new ArrayList<File>();
try {
// setup the factories and file upload stuff
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(999999999);
// create a file item iterator to cycle through all of the files in the req. There SHOULD only be one, though
FileItemIterator iterator = upload.getItemIterator(req);
// iterate through the file items and create a file item stream to output the file
while (iterator.hasNext()) {
// get the file item stream from the iterator
FileItemStream fileItemStream = iterator.next();
// Use the Special InputStream type, passing it the stream and the length of the file
InputStream inputStream = new UploadProgressInputStream(fileItemStream.openStream(), req.getContentLength());
// create a File from the file name
String fileName = fileItemStream.getName(); // this only returns the filename, not the full path
File file = new File(tempDirectory, fileName);
// add the file to the list
fileList.add(file);
// Use commons-io Streams to copy from the inputstrea to a brand-new file
Streams.copy(inputStream, new FileOutputStream(file), true);
// close the inputstream
inputStream.close();
}
} catch (FileUploadException e) {
e.printStackTrace();
}
// now that we've save the file, we can process it.
if (fileList.size() == 0) {
log.debug("No File in the file list. returning.");
return;
}
for (File file : fileList) {
String fileName = file.getName();
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line = reader.readLine();
List<Feature> featureList = new ArrayList<Feature>(); // arraylist may not be the best choice since I don't know how many features I'm importing
while (!line.isEmpty()) {
String[] splitLine = line.split("|");
Feature feature = new Feature();
feature.setId(Integer.parseInt(splitLine[0]));
feature.setName(splitLine[1]);
feature.setFeatureClass(splitLine[2]);
feature.setLat(Double.parseDouble(splitLine[9]));
feature.setLng(Double.parseDouble(splitLine[10]));
featureList.add(feature);
line = reader.readLine();
}
file.delete(); // todo: check this to ensure it won't blow up the code since we're iterating in a for each
reader.close(); // todo: need this in a finally block somewhere to ensure this always happens.
try {
featureService.persistList(featureList);
} catch (ServiceException e) {
log.debug("Caught Service Exception in FeatureUploadService.", e);
}
}
}
It was an incredibly stupid problem. I left the name attribute off of the FileUpload entry in the GWT UiBinder. Thanks for all of the help from everyone.
Are the only request parameters available File items? Because you may want to put in a check:
if (!fileItemStream.isFormField()){
// then process as file
otherwise you'll get errors. On the surface of things your code looks fine: no errors in the Tomcat logs?
You need to add enctype='multipart/form-data' in html form

Categories

Resources