[SPRING+JSP] 파일 업로드 샘플 예제 코드
스프링 환경에서 파일 업로드 기능을 구현하는 예제코드이다.
[fileUploader.jsp]
<%@ page contentType="text/html;charset=UTF-8" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="./lib/external/common/jquery-3.1.1.min.js"></script>
<script>
jQuery(document).ready(function()
{
var url = window.location.search.substring(1);
var strDmn = url.split('=')[1];
jQuery("#DMN").val(strDmn);
jQuery('.search_file').click(function(){ jQuery('input[type="file"]').click(); });
jQuery('input[type="file"]').change(function()
{
jQuery('form ul').html('');
for(var i=0 ; i<this.files.length ; i++)
{
jQuery('form ul').append('<li>'+this.files[i].name+'</li>');
}
});
})
</script>
</head>
<body>
<form:form name="fileUpload" method="POST" action="fileUpload.do" enctype="multipart/form-data" modelAttribute="formData">
<ul>
<li class="no_file">파일을 선택해주세요</li>
</ul>
<div>
<div class="search_file button">파일찾기</div>
<input class='button' type='submit' value='저장'>
</div>
<input type="file" name="files" value='' accept=".gif, .jpg, .png .jpeg">
</form:form>
</body>
</html>
[백엔드 코드]
@RequestMapping(value = {"/fileUpload.do", "/test/fileUpload.do"})
@ResponseBody
public void fileUpload(@ModelAttribute("formData")FileModel formData, HttpServletResponse res, HttpServletRequest req, Model model)
{
try
{
uploadFile(formData, res, req, new FileService());
}
catch(Exception ex)
{
log.info(ex.toString());
}
}
[FileModel.java]
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public class FileModel
{
private List<MultipartFile> files;
public List<MultipartFile> getFiles()
{
return files;
}
public void setFiles(List<MultipartFile> files)
{
this.files = files;
}
}
[FileService.java]
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
@SuppressWarnings("unchecked")
public class FileService extends AbstractFileService
{
@Override
protected int getFileId(MultipartFile file, PathInfo savePath)
{
int intResult = 0;
UserModel userSession = 세션정보;
List<CommonParamMap> saveResult;
CommonParamMap param = new CommonParamMap();
param.put("fileNm", file.getOriginalFilename());
param.put("filePath", savePath.getSaveURL());
param.put("fileExt", FilenameUtils.getExtension(file.getOriginalFilename()));
param.put("fileSize", String.valueOf(file.getSize()));
param.put("userId", userSession.getUserId());
try
{
saveResult = commonDAO.list("common.insertfile", param);
if(!saveResult.isEmpty()) intResult = Integer.parseInt(saveResult.get(0).get("PK_ID").toString());
}
catch (Exception ex)
{
log.error("FileService getFileId() :: " + ex.toString());
log.error(ex.getMessage());
}
return intResult;
}
}
[CommonDAO.java]
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.stereotype.Repository;
import com.ibatis.sqlmap.client.SqlMapClient;
import egovframework.rte.psl.dataaccess.EgovAbstractDAO;
import core.util.AbstractDataEncoder;
import core.util.JSONDataEncoder;
@Repository("commonDAO")
public class CommonDAO extends EgovAbstractDAO implements ApplicationContextAware
{
ApplicationContext appCtx;
private final Map<String, SqlMapClientTemplate> templates = new HashMap<>();
private AbstractDataEncoder encoder = new JSONDataEncoder();
static Logger log = LoggerFactory.getLogger(CommonDAO.class);
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
SqlMapClientTemplate tplInstance;
Map<String, SqlMapClient> clients;
this.appCtx = applicationContext;
boolean isFirst = true;
clients = appCtx.getBeansOfType(SqlMapClient.class);
for(Entry<String, SqlMapClient> entry : clients.entrySet())
{
String key = entry.getKey();
SqlMapClient client = clients.get(key);
tplInstance = new SqlMapClientTemplate();
tplInstance.setSqlMapClient(client);
if(isFirst) super.setSqlMapClient(client);
templates.put(key, tplInstance);
isFirst = false;
}
}
public final SqlMapClientTemplate getSqlMapClientTemplate(String key)
{
if(templates.containsKey(key))
{
return templates.get(key);
}
else
{
return getSqlMapClientTemplate();
}
}
public Object insert(String queryId, Object parameterObject, boolean logging)
{
if(logging)
{
log.info(String.format("INSERT Query executed: %s", queryId));
log.info(String.format("INSERT Parameter: %s", encoder.encode(parameterObject)));
}
return getSqlMapClientTemplate().insert(queryId, parameterObject);
}
public Object insert(String dao, String queryId, Object parameterObject)
{
return getSqlMapClientTemplate(dao).insert(queryId, parameterObject);
}
public Object insert(String dao, String queryId, Object parameterObject, boolean logging)
{
if(logging)
{
log.info(String.format("INSERT Query executed: %s", queryId));
log.info(String.format("INSERT Parameter: %s", encoder.encode(parameterObject)));
}
return getSqlMapClientTemplate(dao).insert(queryId, parameterObject);
}
public int update(String dao, String queryId, Object parameterObject)
{
return getSqlMapClientTemplate(dao).update(queryId, parameterObject);
}
public int delete(String dao, String queryId, Object parameterObject)
{
return getSqlMapClientTemplate(dao).delete(queryId, parameterObject);
}
public Object selectByPk(String dao, String queryId, Object parameterObject)
{
return getSqlMapClientTemplate(dao).queryForObject(queryId, parameterObject);
}
@SuppressWarnings("rawtypes")
public List list(String dao, String queryId, Object parameterObject)
{
return getSqlMapClientTemplate(dao).queryForList(queryId, parameterObject);
}
@SuppressWarnings("rawtypes")
public List listWithPaging(String dao, String queryId, Object parameterObject, int pageIndex, int pageSize)
{
int skipResults = pageIndex * pageSize;
int maxResults = pageSize;
return getSqlMapClientTemplate(dao).queryForList(queryId, parameterObject, skipResults, maxResults);
}
}
[CommonParamMap.java]
import egovframework.rte.psl.dataaccess.util.EgovMap;
public class CommonParamMap extends EgovMap implements Cloneable
{
private static final long serialVersionUID = 3848851032730232522L;
@Override
public Object get(Object key)
{
if(super.containsKey(key))
{
Object obj = super.get(key) == null? "" : super.get(key);
if(obj.getClass().getName().equals("java.sql.Date")) obj = obj.toString();
return obj;
}
else
{
return "";
}
}
}
[JSONDataEncoder.java]
import org.springframework.http.MediaType;
// 객체를 JSON 문자열로 인코딩 하기 위한 클래스.
public final class JSONDataEncoder extends AbstractDataEncoder
{
@Override
protected MediaType getMediaType(){ return MediaType.APPLICATION_JSON; }
@Override
protected String getResultHeader(){ return ""; }
@Override
protected String getResultTail(){ return ""; }
@Override
protected String getNullObjectString(){ return "null"; }
@Override
protected String getWrapOpenString(CodeBlockType type)
{
switch(type)
{
case ARRAY_BLOCK: return "[";
case OBJECT_BLOCK: return "{";
default: return "";
}
}
@Override
protected String getWrapCloseString(CodeBlockType type)
{
switch(type)
{
case ARRAY_BLOCK: return "]";
case OBJECT_BLOCK: return "}";
default: return "";
}
}
@Override
protected String getItemSplitString() { return ","; }
@Override
protected String getObjFormatString() { return String.format(""%s":%s", FMT_OBJ_KEY, FMT_OBJ_VALUE); }
@Override
protected String getArrayItemFormatString(){ return FMT_ARR_ITEM; }
@Override
protected String getValueEscapeString(Object obj)
{
if(Number.class.isAssignableFrom(obj.getClass()))
{
return obj.toString();
}
else if(Boolean.class.isAssignableFrom(obj.getClass()))
{
return obj.toString();
}
else
{
return String.format(""%s"", obj.toString()
.replace("\", "\\")
.replace(""", "\"")
.replace("t", "\t")
.replace("r", "\r")
.replace("n", "\n")
);
}
}
}
[AbstractDataEncoder.java]
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
/**
* @author multic
* 객체 데이터를 문자열로 표현하기 위한 추상클래스.
* 세부 표현 서식을 설정하는 메소드를 구현해 사용하도록 한다.
*/
public abstract class AbstractDataEncoder
{
protected Logger log = LoggerFactory.getLogger(this.getClass());
protected enum CodeBlockType
{
OBJECT_BLOCK,
ARRAY_BLOCK
}
protected static final String FMT_OBJ_KEY = "${OBJ_KEY}$";
protected static final String FMT_OBJ_VALUE = "${OBJ_VALUE}$";
protected static final String FMT_ARR_ITEM = "${ARR_ITEM}$";
private static List<AbstractDataEncoder> encoders = new ArrayList<>();
private final List<Class<?>> primitiveWrappers = new ArrayList<Class<?>>()
{
private static final long serialVersionUID = 5879563143393373308L;
{
super.add(Boolean.class);
super.add(Byte.class);
super.add(Character.class);
super.add(Short.class);
super.add(Integer.class);
super.add(Long.class);
super.add(Float.class);
super.add(Double.class);
super.add(String.class);
}
};
/**
* 생성자 - 객체가 생성될 때 클래스 static 리스트에 현재 객체의 인스턴스를 추가한다.
*/
public AbstractDataEncoder()
{
encoders.add(this);
}
private boolean isValueType(Class<?> cls)
{
return cls.isPrimitive() || primitiveWrappers.contains(cls);
}
public static AbstractDataEncoder getEncoder(String type)
{
for(AbstractDataEncoder enc : encoders)
{
if(enc.getMediaType().getSubtype().toLowerCase(Locale.US).equals(type)) return enc;
}
return null;
}
public String getContentType()
{
return getMediaType().toString();
}
public String encode(Object obj)
{
return String.format("%s%s%s", getResultHeader(), parseObject(obj, 0), getResultTail());
}
private String parseObject(Object obj, int depth)
{
StringBuilder sbResult = new StringBuilder();
if(depth >= 16)
{
return "";
}
if(obj == null)
{
return getNullObjectString();
}
else if(Map.class.isAssignableFrom(obj.getClass()))
{
sbResult.append(parseMap((Map<?, ?>)obj, depth + 1));
}
else if(List.class.isAssignableFrom(obj.getClass()))
{
sbResult.append(parseArray(((List<?>)obj).toArray(), depth + 1));
}
else if(obj.getClass().isArray())
{
int arrSize = Array.getLength(obj);
ArrayList<Object> arrList = new ArrayList<>();
for(int ii = 0; ii < arrSize; ii++)
{
arrList.add(Array.get(obj, ii));
}
sbResult.append(parseArray(arrList.toArray(), depth + 1));
}
else if(isValueType(obj.getClass()))
{
sbResult.append(getValueEscapeString(obj));
}
else
{
sbResult.append(parseClass(obj, depth + 1));
}
return sbResult.toString();
}
private String parseMap(Map<?, ?> src, int depth)
{
boolean isFirst = true;
Set<?> keySet = src.keySet();
StringBuilder sbResult = new StringBuilder();
sbResult.append(getWrapOpenString(CodeBlockType.OBJECT_BLOCK));
for(Object key : keySet)
{
if(!isFirst) sbResult.append(getItemSplitString());
sbResult.append(
getObjFormatString()
.replace(FMT_OBJ_KEY, key.toString())
.replace(FMT_OBJ_VALUE, parseObject(src.get(key), depth + 1))
);
isFirst = false;
}
sbResult.append(getWrapCloseString(CodeBlockType.OBJECT_BLOCK));
return sbResult.toString();
}
private String parseArray(Object[] src, int depth)
{
StringBuilder sbResult = new StringBuilder();
sbResult.append(getWrapOpenString(CodeBlockType.ARRAY_BLOCK));
for(int ii = 0; ii < src.length; ii++)
{
if(ii > 0) sbResult.append(getItemSplitString());
sbResult.append(getArrayItemFormatString().replace(FMT_ARR_ITEM, parseObject(src[ii], depth + 1)));
}
sbResult.append(getWrapCloseString(CodeBlockType.ARRAY_BLOCK));
return sbResult.toString();
}
private boolean validReturnType(Class<?> type)
{
if(type.isArray())
{
return true;
}
else if(void.class.equals(type))
{
return false;
}
else if(Class.class.isAssignableFrom(type))
{
return false;
}
else if(primitiveWrappers.contains(type))
{
return true;
}
else if(Map.class.isAssignableFrom(type))
{
return true;
}
else if(List.class.isAssignableFrom(type))
{
return true;
}
else if(type.isPrimitive())
{
return true;
}
else if(type.isEnum())
{
return true;
}
return false;
}
private String parseClass(Object obj, int depth)
{
StringBuilder sbResult = new StringBuilder();
Map<String, Object> resultMap = new HashMap<>();
sbResult.append(getWrapOpenString(CodeBlockType.OBJECT_BLOCK));
for(Method getter : obj.getClass().getMethods())
{
if(getter.getName().startsWith("get") && getter.getParameterTypes().length == 0)
{
String name = "";
Object result = null;
try
{
name = String.format("%s%s", getter.getName().substring(3, 4).toLowerCase(), getter.getName().substring(4));
result = getter.invoke(obj);
if(result == null || validReturnType(result.getClass()))
{
resultMap.put(name, result);
}
}
catch(Exception ex)
{
log.info(ex.toString());
log.info(ex.getMessage());
}
}
}
int ii = 0;
for(Entry<String, Object> entry : resultMap.entrySet())
{
String key = entry.getKey();
if(ii > 0)
{
sbResult.append(getItemSplitString());
}
sbResult.append(
getObjFormatString()
.replace(FMT_OBJ_KEY, key)
.replace(FMT_OBJ_VALUE, parseObject(resultMap.get(key), depth + 1))
);
ii++;
}
sbResult.append(getWrapCloseString(CodeBlockType.OBJECT_BLOCK));
return sbResult.toString();
}
protected abstract MediaType getMediaType();
protected abstract String getResultHeader();
protected abstract String getResultTail();
protected abstract String getNullObjectString();
protected abstract String getWrapOpenString(CodeBlockType type);
protected abstract String getWrapCloseString(CodeBlockType type);
protected abstract String getValueEscapeString(Object obj);
protected abstract String getItemSplitString();
protected abstract String getObjFormatString();
protected abstract String getArrayItemFormatString();
}
끝