다음과 같이 동일한 이름으로 된 input file name을 submit하면 스프링의 CommonsMultipartResolver 는 “not supported by MultipartResolver” 라는 에러를 뱉어낸다.
<input type=”file” name=”webFile” />
<input type=”file” name=”webFile” />
<input type=”file” name=”webFile” />
이유인 즉슨, 스프링 2.5에서는 동일한 input type name upload를 지원하지 않기 때문이다.
이를 해결하기 위해 검색을 해보니, SimpleFormController를 이용하여 해결을 할 수 있다고 나온다.
하지만 지금 진행하고 있는 프로젝트는 @Controller와 같이 애노테이션 기반으로 개발을 진행하고 있다.
그렇기에 다른 방법을 생각해 봤고, 나는 아래와 같이 처리를 하게 되었다.
1. application-context.xml
<bean id=”multipartResolver” class=”kr.co.company.core.MultiFileSupportCommonsMultipartResolver”>
<property name=”maxUploadSize” value=”${max.file.size}” />
<property name=”uploadTempDir” ref=”uploadDirResource” />
</bean>
2. MultiFileSupportCommonsMultipartResolver class 생성 후 CommonsMultipartResolver를 상속한다.
오버라이딩 해야 할 부분은 parseFileItems 메소드이다.
@Override
@SuppressWarnings({ “rawtypes”, “unchecked” })
protected MultipartParsingResult parseFileItems(List fileItems, String encoding) {
int index = 1;
Map multipartFiles = new HashMap();
Map multipartParameters = new HashMap();
if (logger.isDebugEnabled()) {
logger.debug(” parseFileItems – fileItems size [” + fileItems.size() + “] , encoding [” + encoding + “]”);
}
// 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);
}
if (logger.isDebugEnabled()) {
logger.debug(“fileItem.getContentType() [” + fileItem.getContentType() + “] , fileItem.getString() [” + fileItem.getString()
+ “] , fileItem.getFieldName() [” + fileItem.getFieldName() + “]”);
}
} else {
CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
if (multipartFiles.containsKey(file.getName())) {
multipartFiles.put(index + “dupl_” + file.getName(), file);
index++;
} else {
multipartFiles.put(file.getName(), file);
}
if (logger.isDebugEnabled()) {
logger.debug(“Found multipart file [” + file.getName() + “] of size ” + file.getSize() + ” bytes with original filename [“
+ file.getOriginalFilename() + “], stored ” + file.getStorageDescription());
}
}
}// for
if (logger.isDebugEnabled()) {
logger.debug(” multipartFiles.toString() [” + multipartFiles.toString() + “] , multipartFiles.size [” + multipartFiles.size()
+ “] , multipartParameters.size [” + multipartParameters.size() + “]”);
}
return new MultipartParsingResult(multipartFiles, multipartParameters);
}
빨간색 코드가 중요한 포인트 이며, 동일한 이름으로 된 name이 있으면 index + “dupl_” 이라는 prefix를 붙여 준다.
3. Controller에 다음 코드 추가
List<MultipartFile> mwebBannerFileList = getMultipartFileList(“webFile”, request);
@SuppressWarnings(“unchecked”)
public List<MultipartFile> getMultipartFileList(String fieldName, HttpServletRequest req) throws Exception{
List<MultipartFile> fileList = new ArrayList<MultipartFile>();
MultipartHttpServletRequest multiReq = (MultipartHttpServletRequest)req;
Map<String, MultipartFile> map = multiReq.getFileMap();
Iterator<Map.Entry<String, MultipartFile>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, MultipartFile> entry = iter.next();
String key = entry.getKey();
String fileOrgName = getFileOrgName(key);
if (fileOrgName.equals(fieldName)) {
MultipartFile file = entry.getValue();
fileList.add(file);
}
}
return fileList;
}
private String getFileOrgName(String key) {
String orgName = null;
if (key.indexOf(dupl_) != -1) {
orgName = key.substring(key.indexOf(dupl_) + 5);
} else {
orgName = key;
}
return orgName;
}
이 방법은 같이 일하는 대리님의 소스 코드를 보고 얻은 결과물이다.