Всегда ли apache commons-fileupload должен записывать на диск?

Я использовал fileUpload один раз, чтобы загрузить файлы на один из наших серверов, но теперь я должен сделать что-то другое. Загружаемый файл никогда не будет записан на диск, но вместо этого его следует читать построчно и вставлять в БД - каждая строка представляет купон / скидку - это внутренняя система управления контентом, поэтому файлы никогда не будут больше чем 10 или около того линий, 100 макс.

Я попытался изменить свой рабочий код, чтобы просто использовать BufferedReader и обрабатывать его в процессе чтения, но я получаю исключение NullPointerException (хотя трассировка стека отсутствует, поэтому мне нужно поиграть с log4j, чтобы получить правильный вывод). Кто-нибудь видел пример в сети или знает, что я делаю не так?

Мой фрагмент кода:

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);
        }
    }
}

Нужно ли мне что-то еще делать или мне нужно сначала записать это на диск, а затем прочитать?

2 ответа

Решение

В руководстве пользователя есть немного документации о том, как это сделать:

// 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();
}

Для log4j вам нужен файл свойств, структурированный следующим образом:

# 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

... и для записи трассировки стека, в вашем блоке catch, поместите loggerInstance.error(exceptionInstance.getMessage(), exceptionInstance); и полная трассировка стека будет зарегистрирована, предполагая, что уровень ОШИБКИ также зарегистрирован.

Ошибка, которую я получал, была:

NullPointerException: charsetName

(нет трассировки стека - я предполагаю, что мой log4j не был установлен для этого проекта apache)

В любом случае, это потому, что моя старая версия использовала apache commons-fileupload-1.0, а новая версия использовала 2.0.

В старом (который я забыл иметь код выше), он сделал это:

String enc = request.getCharacterEncoding();

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

Морковные знаки - это то, что бросало ошибку. При использовании 1.0 это всегда возвращалось бы как ненулевое значение, в 2.0 оно возвращалось как нулевое и взрывалось прямо там.

Меняя это на:

this.code = fileItem.getString();

исправил проблему

Другие вопросы по тегам