Domanda

I've used fileUpload once before to upload files on to one our servers but now I have to do something different. The file that is being uploaded will never be written to the disk, but should instead be read line by line and inserted in to the DB - each line represents a coupon/discount - it's an internal content management system, so the files will never be bigger than 10 or so lines, 100 max.

I tried tweeking my working code to just use a BufferedReader and process it as it's read in, but I keep getting a NullPointerException (though the stacktrace is missing so I have to play with log4j to get the proper output). Has anyone seen an example on the web or know what I'm doing wrong?

My code snippet:

BufferedInputStream in = null;
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
String enc = request.getCharacterEncoding();

for (FileItem item : items) {
    if (item.isFormField()) {
       if ("code".equalsIgnoreCase(fileItem.getFieldName()))
          this.code = fileItem.getString(enc);
       ... // set these to local variables
    } else {
        in = new BufferedInputStream(new FileInputStream(item.getInputStream()));
        String line;
        while ((line = br.readLine()) != null)   {
            insert2DB(line);
        }
    }
}

Do I need to do anything else or do I have to write it to disk first then read it?

È stato utile?

Soluzione

The user's guide has a bit of documentation as to how to do this:

// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

// Parse the request
List /* FileItem */ items = upload.parseRequest(request);

Iterator iter = items.iterator();
while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();
    InputStream uploadedStream = item.getInputStream();
    // your database code goes here
    uploadedStream.close();
}

Per log4j, you need a properties file structured as follows:

# Root logger option
log4j.rootLogger=DEBUG, file, us
# Direct log messages to a plaintext log 
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=public_html/news.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.stderr=org.apache.log4j.ConsoleAppender
log4j.appender.stderr.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1} %L - %m%n
log4j.appender.stderr.layout=org.apache.log4j.PatternLayout

... and to log stacktraces, in your catch block, put loggerInstance.error(exceptionInstance.getMessage(), exceptionInstance); and the full stacktrace will be logged, assuming the ERROR level is logged as well.

Altri suggerimenti

the Error I was getting was:

NullPointerException: charsetName

(no stack trace - I'm assuming my log4j wasn't set for this apache project)

Anyways, it's because my old version used apache's commons-fileupload-1.0 and the new version used 2.0.

In the old one (which I forgot to have the code up above), it did this:

String enc = request.getCharacterEncoding();

for (FileItem fileItem:fileItems) {
   if (fileItem.isFormField()) {
      if ("code".equalsIgnoreCase(fileItem.getFieldName()))
          this.code = fileItem.getString(enc);
                                         ^^^

the carrot marks are what was throwing the error. Using 1.0, this would always come back as non-null, in 2.0, it was coming back as null and blowing up right there.

Changing it to:

this.code = fileItem.getString();

fixed the problem

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top