Index: BlossomMultipartRequestWrapper.java =================================================================== --- BlossomMultipartRequestWrapper.java (revision 37629) +++ BlossomMultipartRequestWrapper.java (working copy) @@ -35,42 +35,71 @@ import info.magnolia.cms.beans.runtime.Document; import info.magnolia.cms.beans.runtime.MultipartForm; + +import java.lang.reflect.Method; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.util.Assert; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest; -import javax.servlet.http.HttpServletRequest; -import java.util.LinkedHashMap; -import java.util.Map; /** * Implementation of MultipartHttpServletRequest that exposes multipart files that has been parsed by the Magnolia - * multipart filter. Does not provide handling of request parameters since that's left to the request wrapper - * added by Magnolia. - * + * multipart filter. Does not provide handling of request parameters since that's left to the request wrapper added by + * Magnolia. + * * @see info.magnolia.module.blossom.multipart.BlossomMultipartResolver * @see info.magnolia.cms.beans.runtime.MultipartForm */ public class BlossomMultipartRequestWrapper extends AbstractMultipartHttpServletRequest { + private static final Logger log = LoggerFactory.getLogger(BlossomMultipartRequestWrapper.class); + private MultipartForm multipartForm; public BlossomMultipartRequestWrapper(HttpServletRequest request) { super(request); - multipartForm = (MultipartForm) request.getAttribute(MultipartForm.REQUEST_ATTRIBUTE_NAME); - // The request needs to have been wrapped by the Magnolia multipart filter. Assert.notNull(multipartForm, "Request is not multipart or not already parsed"); } @Override protected void initializeMultipart() { - Map multipartFiles = new LinkedHashMap(); - for (Object o : multipartForm.getDocuments().entrySet()) { - Map.Entry entry = (Map.Entry) o; - multipartFiles.put((String) entry.getKey(), new BlossomMultipartFile((Document) entry.getValue())); + try { + // https://jira.springframework.org/browse/SPR-2784 changed AbstractMultipartHttpServletRequest methods + // Trying first with Spring 3.x, call AbstractMultipartHttpServletRequest method with MultiValueMap parameter. + Method setMultipartSpring3 = AbstractMultipartHttpServletRequest.class.getDeclaredMethod( + "setMultipartFiles", Class.forName("org.springframework.util.MultiValueMap")); + Method multiValueAdd = Class.forName("org.springframework.util.LinkedMultiValueMap").getDeclaredMethod( + "add", Object.class, Object.class); + Object multipartFiles = Class.forName("org.springframework.util.LinkedMultiValueMap").newInstance(); + for (Map.Entry doc : multipartForm.getDocuments().entrySet()) { + multiValueAdd.invoke(multipartFiles, doc.getKey(), new BlossomMultipartFile(doc.getValue())); + } + // We can avoid the setAccessible(true) because it's already a subclass, but maybe it should be done anyway. + setMultipartSpring3.invoke(this, multipartFiles); + } catch (Exception ex) { + // Otherwise try Spring 2.5.x, call AbstractMultipartHttpServletRequest method with Map parameter. + Map multipartFiles = new LinkedHashMap(); + for (Map.Entry doc : multipartForm.getDocuments().entrySet()) { + multipartFiles.put(doc.getKey(), new BlossomMultipartFile(doc.getValue())); + } + try { + Method setMultipartSpring25 = AbstractMultipartHttpServletRequest.class.getDeclaredMethod( + "setMultipartFiles", Map.class); + // We can avoid the setAccessible(true) because it's already a subclass, but maybe it should be done anyway. + setMultipartSpring25.invoke(this, multipartFiles); + } catch (Exception e) { + // + log.error("Unable to initialize multipart request wrapper map.", e); + } } - setMultipartFiles(multipartFiles); } }