Wichtig aktiviert: Diese Frage ist völlig nutzlos gewesen für jeden Frühling Version höher als 3.0.4 als das Thema in diesem Thread diskutiert fixed in dieser Version vor langer Zeit und ist nicht reproduzierbar in späteren Versionen von Spring.Upload mehrerer Dateien mit Spring MVC 3.0.2 nach HiddenHttpMethodFilter wurde
Ich verwende Spring Version 3.0.2. Ich brauche, um mehrere Dateien laden mit dem multiple="multiple"
Attribut eines Dateibrowser wie
<input type="file" id="myFile" name="myFile" multiple="multiple"/>
(und nicht mehrere Dateibrowser so etwas wie die von this answer erklärte man verwenden, ist es in der Tat funktioniert habe ich versucht).
Obwohl keine Versionen von Internet Explorer diesen Ansatz unterstützen, es sei denn, ein passendes jQuery-Plugin/Widget wird verwendet, ist mir im Moment egal (da die meisten anderen Browser dies unterstützen).
Dies funktioniert gut mit commons fileupload aber zusätzlich zur Verwendung RequestMethod.POST
und RequestMethod.GET
Methoden, mag ich auch wie RequestMethod.PUT
und RequestMethod.DELETE
in ihren eigenen entsprechenden Stellen andere Anforderungsmethoden unterstützt und schlugen vor, bis zum Frühjahr verwenden. Um dies zu tun, habe ich Spring mit HiddenHttpMethodFilter
konfiguriert, die gut geht, wie this question angibt.
aber es kann nur eine Datei auf einmal hochladen, obwohl mehrere Dateien im Dateibrowser ausgewählt sind. In der Spring-Controller-Klasse wird eine Methode wie folgt zugeordnet.
@RequestMapping(method={RequestMethod.POST}, value={"admin_side/Temp"})
public String onSubmit(@RequestParam("myFile") List<MultipartFile> files, @ModelAttribute("tempBean") TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response) throws IOException, FileUploadException {
for (MultipartFile file : files) {
System.out.println(file.getOriginalFilename());
}
}
Auch mit dem Anforderungsparameter @RequestParam("myFile") List<MultipartFile> files
, die ein List
vom Typ MultipartFile
(es kann immer nur eine Datei auf einmal hat).
Ich könnte eine Strategie finden, die mit mehreren Dateien arbeiten on this blog wahrscheinlich ist. Ich habe es sorgfältig durchgegangen.
Die Lösung unter der Abschnitt SOLUTION 2 - Verwenden Sie die RAW REQUEST sagt
Wenn jedoch der Kunde darauf besteht, die gleiche Form Eingabe Namen auf unter Verwendung eines solchen als 'Dateien []' oder "Dateien" und dann diesen Namen mit mehreren Dateien bevölkern dann ist ein kleiner Hack wie folgt erforderlich. Wie oben erwähnt, gibt Spring 2.5 eine Exception aus, wenn es den gleichen Formular-Eingabe-Namen des Dateityps mehr als einmal erkennt. CommonsFileUploadSupport - die Klasse, die diese Ausnahme wirft, ist nicht endgültig und die method, die diese Ausnahme wirft so geschützt ist, die Wunder der Vererbung und Subklassen einer einfach beheben/ändern die Logik ein wenig wie folgt. Die Änderung , die ich gemacht habe, ist buchstäblich ein Wort, das einen Methodenaufruf darstellt, der uns ermöglicht, mehrere Dateien zu haben, die unter dem gleichen Formular eingabename eingehen.
Es versucht, das Verfahren zu überschreiben
protected MultipartParsingResult parseFileItems(List fileItems, String encoding){}
der abstrakten Klasse CommonsFileUploadSupport
durch die Erweiterung der Klasse CommonsMultipartResolver
wie
package multipartResolver;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.fileupload.FileItem;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
public final class MultiCommonsMultipartResolver extends CommonsMultipartResolver {
public MultiCommonsMultipartResolver() {}
public MultiCommonsMultipartResolver(ServletContext servletContext) {
super(servletContext);
}
@Override
@SuppressWarnings("unchecked")
protected MultipartParsingResult parseFileItems(List fileItems, String encoding) {
Map<String, MultipartFile> multipartFiles = new HashMap<String, MultipartFile>();
Map multipartParameters = new HashMap();
// Extract multipart files and multipart parameters.
for (Iterator it = fileItems.iterator(); it.hasNext();) {
FileItem fileItem = (FileItem) it.next();
if (fileItem.isFormField()) {
String value = null;
if (encoding != null) {
try {
value = fileItem.getString(encoding);
} catch (UnsupportedEncodingException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Could not decode multipart item '" + fileItem.getFieldName()
+ "' with encoding '" + encoding + "': using platform default");
}
value = fileItem.getString();
}
} else {
value = fileItem.getString();
}
String[] curParam = (String[]) multipartParameters.get(fileItem.getFieldName());
if (curParam == null) {
// simple form field
multipartParameters.put(fileItem.getFieldName(), new String[]{value});
} else {
// array of simple form fields
String[] newParam = StringUtils.addStringToArray(curParam, value);
multipartParameters.put(fileItem.getFieldName(), newParam);
}
} else {
// multipart file field
CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
if (multipartFiles.put(fileItem.getName(), file) != null) {
throw new MultipartException("Multiple files for field name [" + file.getName()
+ "] found - not supported by MultipartResolver");
}
if (logger.isDebugEnabled()) {
logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize()
+ " bytes with original filename [" + file.getOriginalFilename() + "], stored "
+ file.getStorageDescription());
}
}
}
return new MultipartParsingResult(multipartFiles, multipartParameters);
}
}
Was geschieht, ist, dass die letzte Zeile in dem Verfahren parseFileItems()
(die Rückkehranweisung) dh
return new MultipartParsingResult(multipartFiles, multipartParameters);
verursacht einen Fehler bei der Kompilierung, da der erste Parameter multipartFiles
eine Art von Map
von HashMap
aber in Wirklichkeit umgesetzt ist, erfordert es einen Parameter vom TypMultiValueMap<String, MultipartFile>
Es ist ein Konstruktor einer statischen Klasse innerhalb der abstrakten CommonsFileUploadSupport
Klasse,
public abstract class CommonsFileUploadSupport {
protected static class MultipartParsingResult {
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {}
}
}
der Grund könnte sein - diese Lösung ist über die Feder Version 2.5 und ich bin mit dem Frühling Version 3.0.2, die für diese Version ungeeignet sein könnte.
I jedoch versucht, die mit Map
MultiValueMap
auf verschiedene Weise wie das in dem folgenden Codesegment,
MultiValueMap<String, MultipartFile>mul=new LinkedMultiValueMap<String, MultipartFile>();
for(Entry<String, MultipartFile>entry:multipartFiles.entrySet()) {
mul.add(entry.getKey(), entry.getValue());
}
return new MultipartParsingResult(mul, multipartParameters);
aber keinen Erfolg gezeigt, zu ersetzen. Ich bin mir nicht sicher, wie man Map
durch MultiValueMap
ersetzen kann und sogar so tun könnte, entweder. Nachdem Sie das getan, zeigt der Browser die HTTP-Antwort,
HTTP-Status 400-
Art Statusbericht
Nachricht
Beschreibung Die Anfrage vom Client gesendet wurde syntaktisch falsch ().
Apache Tomcat/6.0.26
Ich habe versucht, die Frage wie möglich zu verkürzen, wie ich kann, und ich habe keinen unnötigen Code enthalten.
Wie könnte es möglich gemacht werden, mehrere Dateien hochzuladen, nachdem Spring mit HiddenHttpMethodFilter
konfiguriert wurde?
Dieser Blog zeigt an, dass es eine lange, hohe Priorität Bug ist.
Wenn es keine Lösung bezüglich der Version 3.0.2 (3 oder höher) gibt, muss ich die Spring-Unterstützung für immer deaktivieren und weiterhin commons-fileupolad verwenden, wie von der dritten Lösung in diesem Blog vorgeschlagen, PUT, DELETE und andere Anfrage auslassen Methoden für immer.
Sehr kleine Änderungen an den Code in der parseFileItems()
Methode innerhalb der Klasse MultiCommonsMultipartResolver
könnten es mehrere Dateien machen hochladen, aber ich konnte nicht in meinen Versuchen (wieder mit der Spring-Version 3.0.2 (3 oder höher erfolgreich)).
Das [Jira-Problem] (https://jira.springsource.org/browse/SPR-2784?page=com.atlassian.jira.plugin.system.issuetabpanels%25253Aall-tabpanel), das im Blogpost erwähnt wird, ist behoben seit Version 3.0.4, können Sie versuchen, zu aktualisieren? –
@RC - Danke für diesen Link. Ich habe eine große Anwendung, die mehr als halb fertig ist. Das Ändern des Frameworks kann erfordern, dass der Code an vielen Stellen geändert wird, so dass ich mir nur eine höhere Version für die zukünftigen Projekte vorstellen kann (ich hätte es schon wissen müssen, bevor ich angefangen habe). Vielen Dank. – Tiny
3.0.2 bis 3.0.4 ist ein kleines Upgrade (hauptsächlich Bugfixes, wenn ich die Versionsnummer anschaue), so sollte es schmerzlos sein. Sie sollten es versuchen und es gehen, wenn es funktioniert –