<!-- file upload, download -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
file upload, download
설정을 위한 xml파일 추가
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/servlet-context.xml
/WEB-INF/spring/aop-context.xml
/WEB-INF/spring/file-context.xml <!-- 설정 파일 지정 -->
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
public class DownloadView extends AbstractView {
@Autowired
PdsService service;
// 다운로드를 받을 수 있는 뷰
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("DownloadView renderMergedOutputModel");
File downloadFile = (File)model.get("downloadFile");
String filename = (String)model.get("filename"); // 원본 파일명
int seq = (Integer)model.get("seq");
response.setContentType(this.getContentType());
response.setContentLength((int)downloadFile.length());
// 이 설정은 한글명 파일의 경우 적용된다
filename = URLEncoder.encode(filename, "utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\";"); // 다운로드 받았을 때 원본 파일명으로 바꿔줌
response.setHeader("Content-Transfer-Encoding", "binary;"); // 2진수형태로 받기
response.setHeader("Content-Length", "" + downloadFile.length()); // 내용의 길이. 렌더링
response.setHeader("Pragma", "no-cache;"); // 저장을 할지말지(no-cache : 저장x)
response.setHeader("Expires", "-1;"); // 기한(-1 : 필요없음)
OutputStream os = response.getOutputStream();
FileInputStream fis = new FileInputStream(downloadFile);
// 실제 데이터를 기입
FileCopyUtils.copy(fis, os);
// download count 증가
service.downCount(seq);
if(fis != null) {
fis.close();
}
}
}
: 파일명을 변경해주기 위한 유틸리티
-> 업로드한 파일명과 저장된 파일명이 충돌되지 않도록 해야한다
public class PdsUtil {
// 파일명 -> 변경(time)
// myfile.txt -> 438565452.txt
public static String getNewFileName(String filename) {
String newfilename = "";
String fpost = "";
if(filename.indexOf('.') >= 0) { // 확장자명이 있음
fpost = filename.substring(filename.indexOf('.')); // .부터 시작해서 끝까지 -> .txt
newfilename = new Date().getTime() + fpost; // 438565452 + .txt
} else { // 확장자명이 없음
newfilename = new Date().getTime() + ".back"; // 438565452 + .back
}
return newfilename;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- upload -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600"/> <!-- 업로드했을 때 파일의 최대 크기(바이트) -->
<property name="maxInMemorySize" value="102400"/> <!-- 디스크에 임시 파일을 생성하기 전 메모리에 보관할 수 있는 최대 크기(바이트) -->
<property name="defaultEncoding" value="utf-8"/>
<property name="uploadTempDir" value="upload"/> <!-- upload 폴더에 올라감 -->
</bean>
<!-- download -->
<bean id="downloadView" class="mul.cam.a.util.DownloadView"></bean>
<bean id="downloadViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order">
<value>0</value>
</property>
</bean>
</beans>
create table pds(
seq int auto_increment primary key,
id varchar(50) not null,
title varchar(200) not null,
content varchar(4000) not null,
filename varchar(50) not null, -- not null일 필요 없음
newfilename varchar(50) not null, -- not null일 필요 없음
readcount decimal(8) not null,
downcount decimal(8) not null,
regdate timestamp not null
);
alter table pds
add foreign key(id) references member(id);
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Pds">
<select id="pdslist" resultType="mul.cam.a.dto.PdsDto">
select seq, id, title, content, filename, newfilename, readcount, downcount, regdate
from pds
</select>
<!-- file upload -->
<insert id="uploadPds" parameterType="mul.cam.a.dto.PdsDto">
insert into pds(id, title, content, filename, newfilename, readcount, downcount, regdate)
values(#{id}, #{title}, #{content}, #{filename}, #{newfilename}, 0, 0, now())
</insert>
<!-- downcount -->
<update id="downCount" parameterType="Integer">
update pds
set downcount = downcount + 1
where seq=${seq}
</update>
<!-- file update -->
<update id="updatePds" parameterType="mul.cam.a.dto.PdsDto">
update pds
set title=#{title}, content=#{content}, filename=#{filename}, newfilename=#{newfilename}, regdate=now()
where seq=${seq}
</update>
</mapper>
public interface PdsDao {
int uploadPds(PdsDto dto);
int updatePds(PdsDto dto);
}
@Repository
public class PdsDaoImpl implements PdsDao {
@Autowired
SqlSessionTemplate session;
@Override
public int uploadPds(PdsDto dto) {
return session.insert(ns + "uploadPds", dto);
}
@Override
public int updatePds(PdsDto dto) {
return session.update(ns + "updatePds", dto);
}
}
public interface PdsService {
boolean uploadPds(PdsDto dto);
boolean updatePds(PdsDto dto);
}
@Service
public class PdsServiceImpl implements PdsService {
@Autowired
PdsDao dao;
@Override
public boolean uploadPds(PdsDto dto) {
int count = dao.uploadPds(dto);
return count>0?true:false;
}
@Override
public boolean updatePds(PdsDto dto) {
int count = dao.updatePds(dto);
return count>0?true:false;
}
}
@PostMapping(value="pdsupload.do")
public String pdsupload(PdsDto dto,
@RequestParam(value="fileload", required = false)
MultipartFile fileload, // 파일 업로드
HttpServletRequest req) { // 파일 경로 설정 목적
// filename 취득
String filename = fileload.getOriginalFilename(); // 원본의 파일명
dto.setFilename(filename); // 원본 파일명(DB)
// upload의 경로 설정
// server
String fupload = req.getServletContext().getRealPath("/upload");
// 폴더
// String fupload = "C:\\temp";
System.out.println("fupload: " + fupload);
// 파일명을 충돌되지 않는 명칭(Date)으로 변경
String newfilename = PdsUtil.getNewFileName(filename);
dto.setNewfilename(newfilename); // 변경된 파일명. 실제 파일
File file = new File(fupload + "/" + newfilename); // 파일 생성
try {
// 실제로 파일이 생성 + 기입 = 업로드
FileUtils.writeByteArrayToFile(file, fileload.getBytes());
// DB에 저장
service.uploadPds(dto);
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:pdslist.do"; // controller -> controller로 이동 : redirect
}
@PostMapping(value="filedownLoad.do")
public String filedownLoad(int seq, String filename, String newfilename,
Model model, HttpServletRequest req) {
// 경로
// server
String fupload = req.getServletContext().getRealPath("/upload");
// 폴더
// String fupload = "C:\\temp";
// 다운로드 받을 파일
File downloadFile = new File(fupload + "/" + newfilename);
model.addAttribute("downloadFile", downloadFile); // file 실제 업로드되어 있는 파일명 1677471933041.txt
model.addAttribute("filename", filename); // string 원 파일명 abc.txt
model.addAttribute("seq", seq); // int 다운로드 카운트 증가
return "downloadView";
}
@PostMapping(value="pdsUpdateAf.do")
public String pdsUpdateAf(PdsDto dto,
@RequestParam(value="fileload", required = false)
MultipartFile fileload, // 파일 업로드
HttpServletRequest req) {
String originalFileName = fileload.getOriginalFilename();
if(originalFileName != null && originalFileName.equals("")) { // 파일이 변경되었음
String newfilename = PdsUtil.getNewFileName(originalFileName);
dto.setFilename(originalFileName);
dto.setNewfilename(newfilename);
String fupload = req.getServletContext().getRealPath("/upload");
File file = new File(fupload + "/" + newfilename);
try {
// 새로운 파일로 업로드
FileUtils.writeByteArrayToFile(file, fileload.getBytes());
// db 갱신
service.updatePds(dto);
} catch (IOException e) {
e.printStackTrace();
}
} else { // 파일이 변경되지 않았음
service.updatePds(dto);
}
return "redirect:/pdsdetail.do?seq" + dto.getSeq();
}