Почему сервлет не находит FileItem в многочастном запросе? - PullRequest
1 голос
/ 06 января 2012

Я написал сервлет, который обрабатывает загрузку файлов с помощью библиотеки загрузки файлов Apache commons. Вот часть кода:

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);

    if (isMultipart) {
        try {
            DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();

            // Set size threshold for storing upload
            fileItemFactory.setSizeThreshold(1 * 1024 * 50); // 50 KB

            // Set temporary directory to store uploaded files above threshold size
            fileItemFactory.setRepository(new File(TEMP_DIRECTORY));

            ServletFileUpload upload = new ServletFileUpload(fileItemFactory);

            //HashMap<String, String> params = new HashMap<String, String>();


            FileItemIterator iterator = upload.getItemIterator(request);
            upload.setSizeMax(REQUEST_MAX_SIZE);

            List items = upload.parseRequest(request);
            Iterator it = items.iterator();

            while (it.hasNext()) {
                FileItem item = (FileItem) it.next();

                if(item.isFormField()) {

                } else {
                    String contentType = item.getContentType();
                    String fileName = item.getName();
                    String fieldName = item.getFieldName();
                    boolean isInMemory = item.isInMemory();
                    long sizeInBytes = item.getSize();
                    File uploadedFile = new File(PATH + "new_audio1.amr");

                    item.write(uploadedFile);

                    System.out.println("Field: " + fieldName);
                    System.out.println("File name: " + fileName);
                    System.out.println("Size: " + sizeInBytes);
                    System.out.println("Is in memory:" + isInMemory);
                }
            }

        } catch (Exception ex) {
            throw new ServletException(ex);
        }
    } else {
        throw new ServletException();
    }

По какой-то причине, которая ускользает от меня, список 'items' пуст, поэтому я не могу загрузить загруженный файл.

Для самой загрузки я написал код Java:

File audioFile = new File("C:\\Users\\Soto\\Desktop\\test recording.amr");

    String url = "http://localhost:8080/AudioFileUpload/UploadServlet";
    String charset = "UTF-8";

    // random values
    String latitude = "145";
    String longitude = "132";
    String speed = "0";


    String query;
    try {
        query = String.format("latitude=%s&longitude=%s&speed=%s", URLEncoder.encode(latitude, charset), URLEncoder.encode(longitude, charset), URLEncoder.encode(speed, charset));
    } catch (UnsupportedEncodingException e) {
        query = String.format("latitude=%s&longitude=%s&speed=%s", latitude, longitude, speed);
    }

    HttpClient httpClient = new DefaultHttpClient();
    httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

    HttpPost httpPost = new HttpPost(url + "?" + query);

    MultipartEntity mpEntity = new MultipartEntity();
    ContentBody cbFile = new FileBody(audioFile, "audio/AMR");
    mpEntity.addPart("audioFile", cbFile);

    httpPost.setEntity(mpEntity);

    HttpResponse response = null;
    try {
        response = httpClient.execute(httpPost);
        HttpEntity responseEntity = response.getEntity();
        System.out.println(response.getStatusLine());

        if(responseEntity != null) 
            System.out.println(EntityUtils.toString(responseEntity));

        if(responseEntity != null) {
            EntityUtils.consume(responseEntity);
        }

        httpClient.getConnectionManager().shutdown();

    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Мне кажется, что файл правильно прикреплен и загружен. Я также пытался сделать это через HTML с помощью запроса на отправку multipart / form-data, но файл все еще не был найден.

Что я делаю не так?

EDIT: Я удалил строку в начале doPost () вместе с оператором if:

ServletFileUpload.isMultipartContent(request);

И тогда загрузка работала правильно. Возможно ли, что этот метод использует поток ввода / вывода / чего бы то ни было запроса?

Спасибо

Ответы [ 2 ]

1 голос
/ 06 января 2012

РЕДАКТИРОВАТЬ: я удалил строку в начале doPost () вместе с оператором if:

ServletFileUpload.isMultipartContent(request);

И тогда загрузка работала правильно.Возможно ли, что этот метод использует поток ввода / вывода / чего бы то ни было запроса?

Это странно.Все, что делает этот метод, это проверяет, равен ли метод запроса POST и не начинается ли заголовок Content-Type с multipart/.Вот выдержка из источника последней версии Commons FileUpload API (которая не сильно изменилась за многие годы):

public static final boolean isMultipartContent(
        HttpServletRequest request) {
    if (!"post".equals(request.getMethod().toLowerCase())) {
        return false;
    }
    String contentType = request.getContentType();
    if (contentType == null) {
        return false;
    }
    if (contentType.toLowerCase().startsWith(MULTIPART)) {
        return true;
    }
    return false;
}

Видите, ничего шокирующего.

Возможно, выиспользование очень непонятного / ошибочного контейнера сервлета, который проявляет ошибку, из-за которой тело запроса будет неявно использоваться при вызове request.getMethod() или getContentType().

0 голосов
/ 06 января 2012

Я думаю, что вы забыли установить тип контента?Используйте Fiddler, чтобы увидеть, что происходит на проводе

Почему вы не используете MultiPartPostData

http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/methods/MultipartPostMethod.html

...