개발환경
- Eclipse
- spring, egovFrameWork
- Tomcat 8.5
- oracle 11g
첨부파일을 클릭하면 파일 다운로드가 자동으로 진행될 수 있도록 처리해보겠습니다. 초급 개발자의 이론이므로 간단한 참고만 부탁드립니다.
1. 첨부파일 표출 - 게시판 View 페이지
<table class="table">
<thead class="thead-light">
<tr><th>
<p class="title">${post.title}</p>
<ul class="info">
<li>${post.writer} </li>
<li> | </li>
<li> ${post.dateWrite}</li>
</ul>
</th></tr>
</thead>
<tbody>
<tr>
<td>
${post.content}
</td>
</tr>
<tr>
<td>
첨부파일
</td>
</tr>
<c:forEach items="${files}" var="file" varStatus="idx" step="1">
<tr onclick='downloadFile("${file.filenameReal}")'>
<td class="table-font-center">${file.filenameReal} ${file.fileSize}Byte</td>
</tr>
</c:forEach>
</tbody>
</table>
게시판에서 파일 다운로드가 필요한 View페이지 입니다. View페이지로 왔을 때, 이 게시물에 대한 파일 목록을 나타내었습니다. 첨부파일을 클릭하면 downloadFile([파일이름])메소드가 실행되어 파일 다운로드가 진행됩니다.
comment - 기존 파일 다운로드할 view 페이지 작성하여 사용하지 않았습니다,.
2. javascript - 파일다운로드 메소드
function downloadFile(filename){
const encFileName = encodeURI(filename);
$.ajax({
method:"GET",
url : `fileDownLoad.do`,
success : function(data) {
window.location =`fileDownLoad.do?FileName=${encFileName}`;
},
error:function(request,status){
alert("오류가 발생했습니다.");
}
});
}
2. javascript - (나에게 맞게 수정)
function downloadFile(){
// const encFileName = encodeURI(filename);
$.ajax({
method:"GET",
url : `/fileDownLoad.do`,
success : function(data) {
window.location =`/fileDownLoad.do?FileName=계약서`;
alert('다운 성공');
},
error:function(request,status){
alert("오류가 발생했습니다.");
}
});
}
comment - 링크 수정 및 파일이름은 고정이라 하드코딩으로
3. controller - 요청받기
@RequestMapping(value="/{boardId}/{postId}/fileDownLoad", method=RequestMethod.GET)
public void fileDownLoad(HttpServletRequest request, HttpServletResponse response, @PathVariable int boardId, @PathVariable int postId) throws IOException {
fileService.fileDownLoad(request, response, boardId, postId);
}
게시판의 아이디, 게시글 아이디는 URL로 받고, 파일의 이름은 파라미터로 전달받았습니다. request는 파일이름을 전달받기 위해, response는 파일전송을 위해 service로 넘겨줍니다.
3. controller -(나에게 맞게 수정)
@RequestMapping(value="/fileDownLoad.do", method=RequestMethod.GET)
public void fileDownLoad(HttpServletRequest request, HttpServletResponse response) throws IOException {
lwEstmateService.fileDownLoad(request, response);
}
comment - 정적파일 하나만 받는거라 게시판 아이디, 게시글아이디는 지우고 request, response 만 남깁니다.
4. Service
public boolean fileDownLoad(HttpServletRequest request, HttpServletResponse response, int boardId, int postId) throws IOException {
//(1) 기본 ajax요청 시 응답
String filenameReal = request.getParameter("FileName");
if (filenameReal == null || filenameReal.equals("")) {
return false;
}
//(2) 요청파일 정보 불러오기
FileInfo fileInfo = new FileInfo();
fileInfo.setBoardId(boardId);
fileInfo.setPostId(postId);
fileInfo.setFilenameReal(filenameReal);
fileInfo = dao.selectFileInfo(fileInfo);
//(3) ContentType설정
if (fileInfo.getGroupId().equals("image")) {
response.setContentType(MediaType.MULTIPART_FORM_DATA);
}else {
response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
}
response.setHeader("Content-Disposition", "attachment; fileName=\"" + URLEncoder.encode(filenameReal,"UTF-8")+"\";");
response.setHeader("Content-Transfer-Encoding", "binary");
//(4) 파일읽어 응답하기
byte[] fileByte = FileUtils.readFileToByteArray(new File(uploadPath + "/" +fileInfo.getGroupId() + "/" + fileInfo.getFilenameServer()));
response.getOutputStream().write(fileByte);
response.getOutputStream().flush();
response.getOutputStream().close();
return true;
}
4. Service -(나에게 맞게 수정)
public boolean fileDownLoad(HttpServletRequest request, HttpServletResponse response) throws IOException {
//(1) 기본 ajax요청 시 응답
String filenameReal = request.getParameter("FileName");
if (filenameReal == null || filenameReal.equals("")) {
return false;
}
String fileRoot = properties.getTempFolderPath();
//(3) ContentType설정
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader("Content-Disposition", "attachment; fileName=\"" + URLEncoder.encode("두차 계약서.pdf","UTF-8")+"\";");
response.setHeader("Content-Transfer-Encoding", "binary");
//(4) 파일읽어 응답하기
// byte[] fileByte = FileUtils.readFileToByteArray(new File("C:\\계약서_ver.pdf")); 로컬일떄
byte[] fileByte = FileUtils.readFileToByteArray(new File(fileRoot+"estemate/계약서_ver.pdf"));
response.getOutputStream().write(fileByte);
response.getOutputStream().flush();
response.getOutputStream().close();
return true;
}
comment - 파일정보는 정적파일 하나만 다운받는거라 파일정보 불러오는 부분 지우고 이미지 파일 분류 필요없으니if 문도 지우고 //(3) ContentType설정 부분에 MediaType.APPLICATION_OCTET_STREAM 썻더니 String 타입이 아니라고 에러가 나서 MediaType.APPLICATION_OCTET_STREAM_VALUE 로 변경 경로만 잘 맞춰주면 다운 성공!
PART (1) **************************************
ajax로 get방식을 이용하여 요청했을 때는 파일이름을 지정하여 보내지 않기 때문에, 이러한 경우에는 어떠한 처리도 하지 않도록 하였습니다.
PART (2) **************************************
게시판의 특정 게시물에 있는 파일의 정보를 불러옵니다. 알고 있는 정보는 파일의 이름 뿐이기 때문에 파일의 자세한 정보를 불러옵니다. (파일의 형식 및 확장자, 서버에 저장되어 있는 파일명칭 등)
PART (3) **************************************
이미지는 다른파일들과 ContentType을 다르게 지정하여 응답합니다. image는 multipart/form-data로 전송하고 나머지 파일형식은 "application/octet-stream"으로 지정합니다.
getGroupId는 파일 타입에 따라서 저장되는 폴더를 다르게 설정하기 위하여 임의로 설정한 것이므로 신경쓰지 않으셔도 됩니다. 해당부분은 이미지파일인지 아닌지를 판단하고 있는 것으로 생각해주시기 바랍니다.
java에서 제공하는 패키지에 ContentType을 상수로 지정해둔 MediaType객체가 있습니다. 이것을 이용하면 ContentType을 한눈에 파악할 수 있어 사용하기 편리하며, 오타가 날 확률이 줄어듭니다.
PART (4) **************************************
FileUtils.readFileToByteArray를 통해 전송할 파일을 byte배열로 바꾸어 줍니다. response의 출력스트림을 사용하여 파일을 전송하고, 버퍼를 플러쉬 한 뒤 요청을 종료합니다.
이렇게 지정한 후 파일을 이름을 클릭하면 파일다운로드가 자동으로 진행됩니다.
참고-
출처 : https://joalog.tistory.com/50
'intellij +springboot' 카테고리의 다른 글
[intellij]그래들 스프링부트 프로젝트 시작하기(gradle + springboot) - 1 (0) | 2022.10.04 |
---|---|
intellij github 계정변경 (0) | 2022.02.03 |
intellij 인텔리제이 jdk sdk 버전 변경 (0) | 2021.11.02 |
[github] remote repository 공유가 안될 때 (remote: Repository not found) (0) | 2021.06.11 |
[IntelliJ] IntelliJ + Github 연동하기 (0) | 2021.06.11 |