views:

50

answers:

1

I'm attempting to upload a file into a jsp and then use the file in some other code. My problem is that it comes into the servlet as an Object via the request.getAttribute() call so I don't know what to cast it to.

I have this code so far to try and test what it is but I'm getting a NullPointerException.

test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"&gt;
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Input Test</title>
    </head>
    <body>
        <form action="InputServlet" method="POST">
        <input type="file" name="file1">
        <input type="submit" value="submit">
        </form>
    </body>
</html>

inputservlet.java

public class InputServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)       throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        out.println(request.getAttribute("file1").getClass());
    }

}

Is my understanding of whats going on flawed or am I just coding it up wrong?

Also I'm expecting the type to be Object so if anyone knows what I should cast it too that would be very helpful as well.

+1  A: 

It's likely null because it concerns a brand new and different request. You probably have sent a redirect to the servlet instead of a forward?

Regardless, you should not process the file upload in a JSP file, but in a real servlet class. It's otherwise recipe for trouble since it's a view technology.

See also:


Update: as per your code update, this won't work. You need to set form's enctype to multipart/form-data and use Commons FileUpload to process it in servlet. Also see the given links.

To the point, the multipart/form-data encoding is not supported by the Servlet API prior to 3.0 and the input values are not available by request.getParameter() and consorts. The use of request.getAttribute() here is a misconception. There it is not for. You would need to parse the request.getInputStream() yourself as per RFC2388. You would however like to use Apache Commons FileUpload for this instead of reinventing and maintaining a wheel for years. Apache Commons already did it for you, take benefit of it.

If you're already on Servlet 3.0 (Glassfish v3), then you can use the builtin request.getParts() to gather the items. Most servletcontainers will use Commons FileUpload under the hoods, you only don't see it in the /WEB-INF/lib or the imports, if that disturbs you for some reason.

See also:

BalusC
Nope. I set the action of the form the input is in to call the servlet. I'm simply trying to get the file so I can pass it to a POJO class that deals with it. I'll update my post will my jsp and servlet code so all can see.
controlfreak123
What exactly are you using to parse the file upload? This sounds like as if you're using a 3rd party filter which handles the upload "transparently". Regardless, did you read the links to that you at least *understand* the basics? I.e. how it ought to work *under the hoods*?
BalusC
also I like your first link except for the fact that I don't need to save the file at any point on the filesystem. I just need to get it to my other class that sends it off to the real database where it is stored. I simply need to get it into a java object so I can deal with it.
controlfreak123
after rereading your first link I think I may understand what I need to do. Use the first part that gets the uploaded file into a File object and then convert the file object into a byte[] because thats the type of object i eventually need. Does that sound like it would work?
controlfreak123
Doable, yes. Write to `ByteArrayOutputStream` and use `toByteArray()` to get the `byte[]`. This is however memory hogging. It will allocate as many JVM memory as the file large is. What do you want to do with it in JSP after all?
BalusC
I have XML data about the file already and I need to have the actual file in order to resubmit it to a database. My only concern now is that I will have other dependencies in this project that I will have to add. Not sure if i wouldn't be better off just collecting the name of the file from the initial page and using the regular java.io methods for opening and getting it into a byte[].
controlfreak123
You'll need to parse the request body yourself. You can get it by `request.getInputStream()`. You only need to know the RFC-2388 how such a body can look like: http://www.faqs.org/rfcs/rfc2388.html That's all exactly what Commons FileUpload is doing on a robust manner. I suggest: don't reinvent it. I don't see how extra libraries in the classpath would harm.
BalusC
I will have to consider my options because adding the libraries really isn't up to me because this is a piece of a much much larger project.Thank you for your advice!
controlfreak123
"... because this is a piece of a much much larger project". This is NOT sound reasoning. If you need to do file uploads, get use of the library approved. Explain that it will cost less and reduce bugs ... relative to coding the file upload support yourself.
Stephen C
Stephen C. It turns out they use that package in the project so its not that big of a deal. But I do agree with what you said about it.
controlfreak123
@Balusc I'm trying to use the first example SO post that you gave me. My problem is how you would differentiate between the different fields that "item" would be. If item.isFormField returns true would you just use another if/else block to determine which field it is?
controlfreak123
Just collect in a `Map<String, String[]>` like `request.getParameter()` does under the hoods or maybe more easy a `Map<String, List<String>>` and then process it afterwards. Alternatively, you can also create a Filter which does this all transparently and sets the uploaded files as request attribute. See this article for an example: http://balusc.blogspot.com/2007/11/multipartfilter.html
BalusC
Ah. I understand. But why Map<String, String[]> or Map<String, List<String>> instead of Map<String, String>? Doesn't item.getString() return a String as well as item.getFieldName() ?
controlfreak123
A parameter can contain multiple values for the same name.
BalusC
I see. Well thank you for all your help. I appreciate you taking the time to explain these things to me!
controlfreak123
You're welcome.
BalusC