MultipartRequest not honouring Servlet API

UI Components for JSF
Post Reply
bradskuse
Posts: 1
Joined: 14 Dec 2010, 04:01

16 Dec 2010, 03:35

I am using the file upload component but receive a ClassCastException in MultipartRequest.getParameterMap() when attempting the upload.

I am using Spring Webflow 2.2.1, Primefaces 2.2.RC2, Mojarra 2.0.3 on Tomcat 6.0.29.

The method public Map getParameterMap(); in MultipartRequest, according to the servlet spec should return a Map<String, String[]> but its returning Map<String, List<String>>

Am I being stupid or does this need logging as an issue to be fixed?

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

21 Sep 2011, 20:03

Violating official ServletRequest API is critical issue. Such behavior can (and it does) cause unpredictable behavior.

bradskuse has problems with Spring WebFlow. I spent almost 4 hours trying to solve NullPointerException, which showed up to be caused by ClassCastException in PrettyFaces view handler (covered with NPE by buggy MyFaces phase invocation).

This thread exists for almost a year and the TRUNK still contains this bug. I am going to create bug report immediately.

I have to solve the issue in my project so I will try to post fixed MultipartRequest back here as well.

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

03 Oct 2011, 09:49

Here is the fixed class as I promised (you can just place it on your webapp class path to replace the default one):

Code: Select all

/*
 * Copyright 2009 Prime Technology.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.primefaces.webapp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class MultipartRequest extends HttpServletRequestWrapper {

    private static final Logger logger = Logger.getLogger(MultipartRequest.class.getName());

    // Map of plain request parameters including parameters of the wrapped
    // request (form parameters override parent parameters)
    private Map<String, String[]> allParams;
    // Map of plain form parameters
    private Map<String, List<String>> formParams;
    // Map of file form parameters
    private Map<String, List<FileItem>> fileParams;

    public MultipartRequest(HttpServletRequest request,
            ServletFileUpload servletFileUpload) throws IOException {
        super(request);
        parseRequest(request, servletFileUpload);
    }

    @SuppressWarnings("unchecked")
    private void parseRequest(HttpServletRequest request,
            ServletFileUpload servletFileUpload) throws IOException {
        try {
            List<FileItem> fileItems = servletFileUpload.parseRequest(request);
            createParameterMaps(fileItems);
        } catch (FileUploadException e) {
            logger.severe("Error in parsing fileupload request");
            throw new IOException(e.getMessage());
        }
    }

    private void createParameterMaps(List<FileItem> fileItems) {
        formParams = new TreeMap<String, List<String>>();
        fileParams = new TreeMap<String, List<FileItem>>();
        for (FileItem item : fileItems) {
            if (item.isFormField()) {
                addItem(formParams, item.getFieldName(), item.getString());
            } else {
                addItem(fileParams, item.getFieldName(), item);
            }
        }
    }

    private <T> void addItem(Map<String, List<T>> params, String name, T value) {
        if (!params.containsKey(name)) {
            params.put(name, new ArrayList<T>());
        }
        params.get(name).add(value);
    }

    @Override
    public String getParameter(String name) {
        String[] values = getParameterMap().get(name);
        return values != null ? values[0] : null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Map<String, String[]> getParameterMap() {
        if (allParams == null) {
            allParams = new TreeMap<String, String[]>(super.getParameterMap());
            for (Map.Entry<String, List<String>> param : formParams.entrySet()) {
                allParams.put(param.getKey(), param.getValue().toArray(
                        new String[param.getValue().size()]));
            }
        }
        return Collections.unmodifiableMap(allParams);
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(getParameterMap().keySet());
    }

    @Override
    public String[] getParameterValues(String name) {
        return getParameterMap().get(name);
    }

    public FileItem getFileItem(String name) {
        if (!fileParams.containsKey(name)) {
            return null;
        }
        return fileParams.get(name).get(0);
    }

    // Workaround to mimic ajax request since flash does not allow custom request headers
    @Override
    public String getHeader(String name) {
        if (name != null && name.equalsIgnoreCase("Faces-Request")) {
            return "partial/ajax";
        } else {
            return ((HttpServletRequest) getRequest()).getHeader(name);
        }
    }

}
Unfortunately I've discovered another two Primefaces' bugs after fixing this one regarding FileUpload component.... but that is for another thread :).

cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

03 Oct 2011, 09:55

Please file issues(one for each), we'll fix them.

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: Google [Bot] and 54 guests