spring 2.5 not supported by MultipartResolver 발생 시 해결 방법

다음과 같이 동일한 이름으로 된 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;

}

이 방법은 같이 일하는 대리님의 소스 코드를 보고 얻은 결과물이다.