[Spring] 자료실(File upload, download, update)

seonjeong·2023년 3월 1일
0

Spring

목록 보기
11/27
post-thumbnail

🔥 라이브러리 추가

<!-- file upload, download -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.3</version>
</dependency>

🔥 web.xml

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>

🔥 Utility 생성

🧾 DownloadView

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();
		}
	}
}

🧾 PdsUtil.java

: 파일명을 변경해주기 위한 유틸리티
-> 업로드한 파일명과 저장된 파일명이 충돌되지 않도록 해야한다

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;
	}
}

🔥 Spring 환경 설정

🧾 file-context.xml

<?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>

🔥 DB

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);

🔥 sql (쿼리문 작성)

🧾 pds.xml

<?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>  

🔥 Dao, Service, Controller

🧾 Dao

  • inerface
public interface PdsDao {
	int uploadPds(PdsDto dto);
	int updatePds(PdsDto dto);
}
  • class
@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);
	}

}

🧾 Service

  • interface
public interface PdsService {
	boolean uploadPds(PdsDto dto);
	boolean updatePds(PdsDto dto);
}
  • class
@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;
	}
}

🧾 Controller

  • File upload
@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
}
  • File download
@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";
 }
  • File update
@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();
}
profile
🦋개발 공부 기록🦋

0개의 댓글

관련 채용 정보