Servlet 3 multipart request implements getParameterNames defensively (for WebLogic 12 compatibility)

This commit also includes lazy resolution support for StandardServletMultipartResolver, along the lines of existing lazy mode in CommonsMultipartResolver.

Issue: SPR-11074
Issue: SPR-11730
master
Juergen Hoeller 10 years ago
parent f29d6eb5f6
commit 82336c320d
  1. 15
      spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java
  2. 56
      spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java
  3. 20
      spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,7 +19,7 @@ package org.springframework.web.multipart.support;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
@ -33,6 +33,8 @@ import org.springframework.web.multipart.MultipartFile;
* {@link org.springframework.web.multipart.MultipartHttpServletRequest}
* interface. Provides management of pre-generated parameter values.
*
* <p>Used by {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}.
*
* @author Trevor D. Cook
* @author Juergen Hoeller
* @author Arjen Poutsma
@ -75,12 +77,17 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
@Override
public Enumeration<String> getParameterNames() {
Set<String> paramNames = new HashSet<String>();
Map<String, String[]> multipartParameters = getMultipartParameters();
if (multipartParameters.isEmpty()) {
return super.getParameterNames();
}
Set<String> paramNames = new LinkedHashSet<String>();
Enumeration<String> paramEnum = super.getParameterNames();
while (paramEnum.hasMoreElements()) {
paramNames.add(paramEnum.nextElement());
}
paramNames.addAll(getMultipartParameters().keySet());
paramNames.addAll(multipartParameters.keySet());
return Collections.enumeration(paramNames);
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
@ -45,22 +49,47 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
private static final String FILENAME_KEY = "filename=";
private Set<String> multipartParameterNames;
/**
* Create a new StandardMultipartHttpServletRequest wrapper for the given request.
* Create a new StandardMultipartHttpServletRequest wrapper for the given request,
* immediately parsing the multipart content.
* @param request the servlet request to wrap
* @throws MultipartException if parsing failed
*/
public StandardMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException {
this(request, false);
}
/**
* Create a new StandardMultipartHttpServletRequest wrapper for the given request.
* @param request the servlet request to wrap
* @param lazyParsing whether multipart parsing should be triggered lazily on
* first access of multipart files or parameters
* @throws MultipartException if an immediate parsing attempt failed
*/
public StandardMultipartHttpServletRequest(HttpServletRequest request, boolean lazyParsing) throws MultipartException {
super(request);
if (!lazyParsing) {
parseRequest(request);
}
}
private void parseRequest(HttpServletRequest request) {
try {
Collection<Part> parts = request.getParts();
this.multipartParameterNames = new LinkedHashSet<String>(parts.size());
MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<String, MultipartFile>(parts.size());
for (Part part : parts) {
String filename = extractFilename(part.getHeader(CONTENT_DISPOSITION));
if (filename != null) {
files.add(part.getName(), new StandardMultipartFile(part, filename));
}
else {
this.multipartParameterNames.add(part.getName());
}
}
setMultipartFiles(files);
}
@ -95,6 +124,29 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
}
@Override
protected void initializeMultipart() {
parseRequest(getRequest());
}
@Override
public Enumeration<String> getParameterNames() {
if (this.multipartParameterNames == null) {
initializeMultipart();
}
if (this.multipartParameterNames.isEmpty()) {
return super.getParameterNames();
}
Set<String> paramNames = new LinkedHashSet<String>();
Enumeration<String> paramEnum = super.getParameterNames();
while (paramEnum.hasMoreElements()) {
paramNames.add(paramEnum.nextElement());
}
paramNames.addAll(this.multipartParameterNames);
return Collections.enumeration(paramNames);
}
@Override
public String getMultipartContentType(String paramOrFileName) {
try {

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -45,6 +45,22 @@ import org.springframework.web.multipart.MultipartResolver;
*/
public class StandardServletMultipartResolver implements MultipartResolver {
private boolean resolveLazily = false;
/**
* Set whether to resolve the multipart request lazily at the time of
* file or parameter access.
* <p>Default is "false", resolving the multipart elements immediately, throwing
* corresponding exceptions at the time of the {@link #resolveMultipart} call.
* Switch this to "true" for lazy multipart parsing, throwing parse exceptions
* once the application attempts to obtain multipart files or parameters.
*/
public void setResolveLazily(boolean resolveLazily) {
this.resolveLazily = resolveLazily;
}
@Override
public boolean isMultipart(HttpServletRequest request) {
// Same check as in Commons FileUpload...
@ -57,7 +73,7 @@ public class StandardServletMultipartResolver implements MultipartResolver {
@Override
public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
return new StandardMultipartHttpServletRequest(request);
return new StandardMultipartHttpServletRequest(request, this.resolveLazily);
}
@Override

Loading…
Cancel
Save