Link to home
Start Free TrialLog in
Avatar of Afterlife
AfterlifeFlag for United States of America

asked on

JSP image upload

Need someone to point me in the direction of a image upload tutorial or something along those lines for JSP pages.
 - please note that I do not need anything to do with taglibs, struts or anything of this nature, just JSP/Servlets will be fine, maybe even java beans.

- i dont want the mimeparser from oop-research.com, nor the Oreiily app for doing this.

What I want to do at the end of the day, is upload image(s) onto a server, store the imagename with its path in the database, and then be able to pull the database image paths and display, the latter being farily simplistic I think, its getting the images uploaded. Ive searched google for about an hour, and found nothing but pre made api's, taglibs, or something other I either have to pay for or get licensed. PHP and ASP.NET seem to have an abundance of help on this topic, Java has very little.

If someone could help me do this, point me in the right direction, I would be grateful.

If this is simply too much work, and someone knows an easy way using a free way (plz no struts, something rather simplistic still, like maybe a taglib but not jstl 2.0) then please post that and I will consider it.

Thankyou in advance


Avatar of tomgallo
tomgallo

You have 2 parts to understand. The first is the JSP (or HTML) and here goes the example for a form to upload a file:

<FORM NAME="frmAccProfileResume" METHOD="POST" ACTION="/servlet?event=upload" ENCTYPE="multipart/form-data">
      <INPUT SIZE="40" TYPE="FILE" NAME="filename" VALUE="Browse">      <INPUT TYPE="submit" VALUE="Upload File">
</FORM>

---------------------------------------------------------------------------------------------
And the second part is the servlet or bean that do the upload process, here I give you a function to do an upload from the request:

  //Upload a file to the server
  public void doUpload(HttpServletRequest request, String Path) throws IOException {
        
        //Gets the ContentType       
      if ((request.getContentType() != null) && (request.getContentType().indexOf("multipart/form-data") >= 0)) {
            
            //Creates the Input Stream
              DataInputStream in = new DataInputStream(request.getInputStream());
              
              //Set the Form data length
              int formDataLength = request.getContentLength();
              
              //Create the buffer to store the file
              byte dataBytes[] = new byte[formDataLength];
              int byteRead = 0;
              int totalBytesRead = 0;
               
             //Reads the InputStream
            while (totalBytesRead < formDataLength) {
                  byteRead = in.read(dataBytes, totalBytesRead, formDataLength);
                  totalBytesRead += byteRead;
            }

            //Set a new string with the file content
            String file = new String(dataBytes);
            
            //Set the name of the file
            String saveFile = file.substring(file.indexOf("filename=\"") + 10);
            
            saveFile = saveFile.substring(0, saveFile.indexOf("\n"));
            saveFile = saveFile.substring(saveFile.lastIndexOf("\\") + 1,saveFile.indexOf("\""));

            //Sets the last index and the final boundary
            int lastIndex = request.getContentType().lastIndexOf("=");
            String boundary = request.getContentType().substring(lastIndex + 1,request.getContentType().length());

            //Set the position to save the file
            int pos;
            pos = file.indexOf("filename=\"");
            pos = file.indexOf("\n", pos) + 1;
            pos = file.indexOf("\n", pos) + 1;
            pos = file.indexOf("\n", pos) + 1;

            //Sets the start and end positions
            int boundaryLocation = file.indexOf(boundary, pos) - 4;
            int startPos = ((file.substring(0, pos)).getBytes()).length;
            int endPos = ((file.substring(0, boundaryLocation)).getBytes()).length;
            
            //Creates the file physically
            FileOutputStream fileOut = new FileOutputStream(Path+saveFile);
            
            //Saves the file to the disk
            //fileOut.write(dataBytes);
            fileOut.write(dataBytes, startPos, (endPos - startPos));
            fileOut.flush();
            fileOut.close();
      }
 
Hope it helps,
-tom
Another comment:

If you want to return the filename and path value in the fucntion (to save it in the database), you only have to add this line at the end of the function:

return Path+saveFile;

And also correct the return value from "void" to "String"

-tom
Avatar of Afterlife

ASKER

Thanks Tom for the quick reply, I will give this a test when I am home tonight, if all works as hoped points will be yours. Just a few quick additions, if you have the time would appreciate an answer, tho they do not pertain to you getting the point for this.

For expanding on this, is it possible to set the maximum size of the file, restirct the type of file uploaded, and width/height properties max. I am looking for something along the lines of how some forums have the upload avatar, where it checks if file is appropriate size/dimensions/type. Seems JSP is harder to do things like this than php etc.

Is this the best way for doing an upload? If you know of easier/better ways please point me in the direction of learning about these.
Also where did you figure out how to do the above, a book? forum?

I am trying to learn j2ee technologies at a comfortable pace, but finding the resources on the net lacking compared to that of asp or php.
Do you know of any links that would be helpful, for tutorials on learning this stuff, any real good books I should take a look at, forums etc.

phpfreaks is probably the best php site out there and was hoping for a jsp equivalent.
Would using the "The Commons  FileUpload  package by Jakarta" be easier than trying to do this myself?

found this page on solutions
http://jguru.com/faq/view.jsp?EID=160
I don't think so... but if you try, please write me and let me know.

The code that I posted is working for my project and it was tested a lot.
I don't know if my approach is the best way to do it, however I can tell you that it works for sure. =)

About the restrictions (file type/size) I'm still working on that.

If you are looking for books on J2SE or J2EE/JSP/JavaScript, the best are in: www.wrox.com
The series "Beginning Java 2" by Ivor Horton are excellent for your pace! =)

-tom
Thanks tom, I'm going to test your file upload soon. I am very intrested in further development you make on your file upload, is there anyway we can keep in contact outside of ee? thanks.
Of course,
here is my email address: tomgallo@speedy.com.ar feel free to write me.

-tom
Ok tried using the upload thing you posted.

so this is what I have basically
<form method="post" action="eventServlet" enctype="multipart/form-data">

<table>
      <tr>
            <td>Event: <input size="50" type="text" name="event" /></td>
      </tr>
      
      <tr>
            <td>Description: <textarea cols="50" rows="10" name="description"></textarea><br /><br /></td>
      </tr>
      
      <tr>
            <td>Flyer/Image<input type="file" size="40" name="filename" value="Browse" /><br /><br /></td>
      </tr>
      
      <tr>
            <td><input type="submit" name="submit" value="Upload File" /></td>
      </tr>
</table>
<input type="hidden" name="action" value="upload" />
</form>

so then in the servlet i do this

String action = request.getParameter("action");
                String submit = request.getParameter("submit");
                String address;
                
                out.println("action is: " + action);
                out.println("submit is: " + submit);

now it should print the values, but instead prints null...

i took out the
<tr>
            <td>Flyer/Image<input type="file" size="40" name="filename" value="Browse" /><br /><br /></td>
</tr>

from the form and it works, but when i add back in it doesnt. Any ideas? I need the values as a way of checking what the servlet should do.

thanks
Yes!

Beacuse the form is a enctype="multipart/form-data".
You have to use different forms to do that... the form for the file, and the form for the hidden

Try this out!

-tom
Another comment:
To call several submits in one click you have to do a simple Javascript function like this:

function doUpload(){
      document.frmOne.submit();
      document.frmTwo.submit();
}

One thing to keep in mind is that you need now two different servlets, one for the upload, the other for the additional data (you can use one, but is not the best practice in this case).
Also you can execute the javascript function in the onClick event of the submit input.

Hope it helps,
-tom
Hey tom, for now just trying to get it to upload to a certain folder.

I did this. Servlet grabs the form data, and then instantly calls your doUpload with this

doUpload(request, "/images/"); // as images is the folder I want to store the file in.

anyways the exception im getting is this

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.io.FileNotFoundException: /images/test.txt (No such file or directory)
      at java.io.FileOutputStream.open(Native Method)
      at java.io.FileOutputStream.(FileOutputStream.java:179)
      at java.io.FileOutputStream.(FileOutputStream.java:70)
      at eventServlet.doUpload(eventServlet.java:132)
      at eventServlet.doPost(eventServlet.java:40)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:594)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:392)
      at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
      at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
      at java.lang.Thread.run(Thread.java:534)



test.txt is the file ive uploaded, and image/ is the path I want to insert it to. Am I misuing your path setting when calling the doUpload, is path supposed to be the path the file is located at? if so how do I specify this?
You have to pass the full path to the function, not only the partial path.
The exception is because does not find the folder.

-tom
the path is where do you want to save the file.

-tom
well i want to save it on the server, cant I specify the path to be relative? like when i call a jsp i do it relativly ie "hello.jsp", the folder images exists as as sub dir to the jsp, the jsp sends the request to a servlet which then does the save, im gettin the exception because it cant find the folder, but the folder /images/ exists.


Any ideas?
You do that because the Application Server knows the filesystem, but here you are accessing direct to the filesystem not through the Application Server. In fact the folder exists but the path to it is incorrect.
This process (servlet) runs in the server and knows the filesystem, you have to specify the correct path to save a file into the filesystem otherwise the AS will throw an exception.

-tom
so how do i go about specifing the absolute path?
Where do you want to save the file?

For example, in my case I call the function like this:
doUpload(request, "/Applications/eclipse/workspace/HydraNet/Resumes/");

If your website is in, for example: /private/system/websiteroot and you have an "images" folder in it, you have to call the function like this:
doUpload(request, "/private/system/websiteroot/images/");
Another thing... of course you have to have write permission in the /images folder
well atm until i get the new username/pw for the server, im forced to use the university server as its the only way i can test jsp pages for free ;). How would i go about setting up the path and making sure that people can upload images?
ASKER CERTIFIED SOLUTION
Avatar of tomgallo
tomgallo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks tom, got it working!

I will stay in touch to see what further developments you add to this :)

Thanks again.