重要:このスレッドで説明されている問題はかなり前にそのバージョンで修正されており、Springの後続のバージョンでは再現できなくなっているため、この質問は3.0.4より後のSpringバージョンではまったく役に立ちません。
Springバージョン3.0.2を使用しています。multiple="multiple"
次のようなファイルブラウザの属性を使用して、複数のファイルをアップロードする必要があります。
<input type="file" id="myFile" name="myFile" multiple="multiple"/>
(そして、この回答で述べられているような複数のファイルブラウザを使用していないので、実際に試してみました)。
適切なjQueryプラグイン/ウィジェットが使用されていない限り、Internet Explorerのどのバージョンもこのアプローチをサポートしていませんが、今は気にしません(他のほとんどのブラウザーがこれをサポートしているため)。
これはcommonsfileuploadRequestMethod.POST
で正常に機能しますが、メソッドの使用に加えて、Springによってサポートおよび提案されている他のリクエストメソッドを適切な場所でRequestMethod.GET
使用したいと思いますRequestMethod.PUT
。これを行うために、この質問が示すようにうまくいくRequestMethod.DELETE
Springを構成しました。HiddenHttpMethodFilter
ただし、ファイルブラウザで複数のファイルが選択されている場合でも、一度にアップロードできるファイルは1つだけです。Springコントローラークラスでは、メソッドは次のようにマップされます。
@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());
}
}
タイプのリクエストパラメータ@RequestParam("myFile") List<MultipartFile> files
を使用する場合でも(一度に1つのファイルのみを持つことができます)。List
MultipartFile
このブログで、複数のファイルで機能する可能性のある戦略を見つけることができました。私はそれを注意深く調べました。
セクションソリューション2の下のソリューション–RAWリクエストを使用すると次のようになります。
ただし、クライアントが「files[]」や「files」などの同じフォーム入力名を使用し、その名前に複数のファイルを入力することを要求する場合は、次のように小さなハックが必要です。上記のように、Spring 2.5は、ファイルタイプの同じフォーム入力名を複数回検出した場合に例外をスローします。CommonsFileUploadSupport –その例外をスローするクラスはfinalではなく、その例外をスローするメソッドは保護されているため、継承の驚異を使用してサブクラス化すると、次のようにロジックを少し修正/変更できます。私が行った変更は、文字通り1つのメソッド呼び出しを表す1つの単語であり、同じフォーム入力名で複数のファイルを受信できるようにします。
メソッドをオーバーライドしようとします
protected MultipartParsingResult parseFileItems(List fileItems, String encoding){}
次のようなクラスCommonsFileUploadSupport
を拡張することによる抽象クラスのCommonsMultipartResolver
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);
}
}
何が起こるかというと、メソッドの最後の行parseFileItems()
(returnステートメント)、つまり
return new MultipartParsingResult(multipartFiles, multipartParameters);
最初のパラメータはによって実装されmultipartFiles
たタイプであるため、コンパイル時エラーが発生しますが、実際には、タイプのパラメータが必要です。Map
HashMap
MultiValueMap<String, MultipartFile>
これは、抽象クラス内の静的クラスのコンストラクターですCommonsFileUploadSupport
。
public abstract class CommonsFileUploadSupport {
protected static class MultipartParsingResult {
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {}
}
}
理由はおそらく-この解決策はSpringバージョン2.5に関するものであり、私はSpringバージョン3.0.2を使用していますが、これはこのバージョンには不適切である可能性があります。
ただし、次のコードセグメントに示すようなさまざまな方法でMap
、を置き換えようとしました。MultiValueMap
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);
しかし、成功しません。交換する方法がわかりません。交換Map
するMultiValueMap
こともできます。これを行った後、ブラウザはHttp応答を表示します。
HTTPステータス400-
タイプステータスレポート
メッセージ
descriptionクライアントから送信された要求は構文的に正しくありませんでした()。
Apache Tomcat / 6.0.26
質問をできるだけ短くするように努めましたが、不要なコードは含めていません。
Springを設定した後、どうすれば複数のファイルをアップロードできるようになりますHiddenHttpMethodFilter
か?
そのブログは、それが長年の、優先度の高いバグであることを示しています。
バージョン3.0.2(3以降)に関する解決策がない場合は、Springサポートを永久に無効にし、そのブログの3番目の解決策で提案されているようにcommons-fileupoladを引き続き使用し、PUT、DELETE、およびその他の要求メソッドを永久に省略します。 。
parseFileItems()
クラス内のメソッドのコードにほとんど変更を加えないと、MultiCommonsMultipartResolver
複数のファイルがアップロードされる可能性がありますが、試行に成功しませんでした(Springバージョン3.0.2(3以降)でも)。