[SPRING] HiddenHttpMethodFilter가 활성화 된 후 Spring MVC 3.0.2를 사용하여 여러 파일 업로드하기
SPRINGHiddenHttpMethodFilter가 활성화 된 후 Spring MVC 3.0.2를 사용하여 여러 파일 업로드하기
중요 :이 질문은이 스레드에서 논의 된 문제가 이전 버전에서 수정되어 Spring의 후속 버전에서 더 이상 재현 할 수 없으므로이 질문은 3.0.4 이상의 모든 Spring 버전에서는 전혀 쓸모가 없습니다.
Spring 버전 3.0.2를 사용하고 있습니다. 파일 브라우저의 multiple = "multiple"속성을 사용하여 여러 파일을 업로드해야합니다.
<input type="file" id="myFile" name="myFile" multiple="multiple"/>
(그리고이 답변에 명시된 것과 같은 여러 파일 브라우저를 사용하지 않고, 실제로 시도해 보았습니다).
적절한 jQuery 플러그인 / 위젯을 사용하지 않으면 Internet Explorer 버전에서이 방법을 지원하지 않지만 지금 당장은별로 신경 쓰지 않습니다 (대부분의 다른 브라우저가이를 지원하므로).
이것은 commons fileupload와 잘 동작하지만 RequestMethod.POST와 RequestMethod.GET 메소드를 사용하는 것 외에도 Spring이 지원하고 RequestMethod.PUT과 RequestMethod.DELETE와 같은 다른 요청 메소드를 적절한 위치에 사용하고자합니다. 이를 위해, 나는 HiddenHttpMethodFilter를 사용하여 Spring을 구성했다.
파일 브라우저의 여러 파일을 선택하더라도 한 번에 하나의 파일 만 업로드 할 수 있습니다. 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
이 블로그에서 여러 파일로 작업 할 가능성이 높은 전략을 찾을 수있었습니다. 나는 그것을 조심스럽게 지나쳤다.
해결책 2 - 원시 요청 사용 아래의 해결책은,
메서드를 재정의하려고 시도합니다.
protected MultipartParsingResult parseFileItems(List fileItems, String encoding){}
CommonsMultipartResolver 클래스를 확장하여 추상 클래스 CommonsFileUploadSupport의 인스턴스를 만들고,
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가 HashMap에 의해 구현 된 Map 유형이기 때문에 컴파일 타임 오류가 발생하지만 실제로는 MultiValueMap
이것은 추상 클래스 인 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 응답을 표시하고,
가능한 한 질문을 줄이고 불필요한 코드를 포함시키지 않았습니다.
HiddenHttpMethodFilter로 Spring을 설정 한 후에 어떻게 여러 파일을 업로드 할 수 있습니까?
이 블로그는 오랜 순위의 최우선 순위의 버그임을 나타냅니다.
버전 3.0.2 (3 이상)에 대한 해결책이 없다면 Spring 지원을 영구적으로 사용 중지하고 PUT, DELETE 및 기타 요청 메소드를 생략 한 블로그의 세 번째 솔루션에서 제안한대로 commons-fileupolad를 계속 사용해야합니다. .
MultiCommonsMultipartResolver 클래스의 parseFileItems () 메소드의 코드를 약간 변경하면 여러 파일을 업로드 할 수는 있지만 스프링 시도 3.0.2 (3 이상)에서 성공할 수는 없습니다.
해결법
-
==============================
1.하나의 요청으로 여러 파일 업로드의 경우이 코드를 사용했습니다.
하나의 요청으로 여러 파일 업로드의 경우이 코드를 사용했습니다.
나는 그런 JSP를 가지고있다 :
<p>Select files to upload. Press Add button to add more file inputs.</p> <table> <tr> <td><input name="files" type="file" multiple="true"/></td> </tr> <tr> <td><input name="files" type="file" multiple="true"/></td> </tr> </table> <br/><input type="submit" value="Upload" />
파일 업로드 클래스 bean :
import org.springframework.web.multipart.commons.CommonsMultipartFile; public class FileUploadForm { private CommonsMultipartFile [] files; public CommonsMultipartFile[] getFiles() { return files; } public void setFiles( CommonsMultipartFile[] files ) { this.files = files; } }
제어 장치:
@Controller @RequestMapping("/upload") public class FileUploadController { @RequestMapping(method = RequestMethod.GET) public String displayForm(ModelMap modelMap) { modelMap.addAttribute( new FileUploadForm() ); return "uploadForm.jsp"; } @RequestMapping(method = RequestMethod.POST) public String save(FileUploadForm uploadForm) { CommonsMultipartFile[] files = uploadForm.getFiles(); if(files != null && files.length != 0) { for(MultipartFile file : files) { System.out.println( file.getOriginalFilename() ); } } return "success.jsp"; } }
이 코드는 하나의 요청으로 여러 파일을 업로드 할 수있게 해주 며, 각 파일에 대해 CommonsMultipartFile의 인스턴스를 가져올 수 있어야합니다.
-
==============================
2.질문에서 언급 한 문제는 Spring 3.0.4에서 수정되었습니다. 따라서 해당 버전 이상을 사용했다면 (예, 현재 4.x.x입니다.)이 질문 / 답변을 더 이상 읽을 필요가 없습니다.
질문에서 언급 한 문제는 Spring 3.0.4에서 수정되었습니다. 따라서 해당 버전 이상을 사용했다면 (예, 현재 4.x.x입니다.)이 질문 / 답변을 더 이상 읽을 필요가 없습니다.
from https://stackoverflow.com/questions/13686757/uploading-multiple-files-using-spring-mvc-3-0-2-after-hiddenhttpmethodfilter-has by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring : String Bean을 생성자에 삽입하는 방법은 무엇입니까? (0) | 2019.02.08 |
---|---|
[SPRING] 대문자와 소문자를 구별하지 않는 Spring CrudRepository의 쿼리 (0) | 2019.02.08 |
[SPRING] Spring AOP : 인수 이름에 접근하기 (0) | 2019.02.08 |
[SPRING] Spring Boot 앱에서 API 게이트웨이를 사용할 때 HATEOAS 경로가 유효하지 않습니다. (0) | 2019.02.08 |
[SPRING] Spring Security SAML + HTTPS를 다른 페이지로 (0) | 2019.02.08 |