본문 바로가기
Spring

2022-12-15 파일다운로드

by HTT 2022. 12. 15.

다른 부분은 딱히 설명이 필요하지 않으므로 컨트롤러, 뷰만 정리

BoardFileDTO
public class BoardFileDTO {
	private String board_no;
	private String originalFilename;
	private String storeFilename; 
	private String boardFileno;
	생성자, 메소드 생략
}

 

 

BoardServiceImpl
public class BoardServiceImpl implements BoardService{
    public BoardFileDTO getFile(BoardFileDTO inputdata) {
        return dao.getFile(inputdata);
    }
}

 

 

BoardDAOImpl
public class BoardDAOImpl implements BoardDAO{
    public BoardFileDTO getFile(BoardFileDTO inputdata) {
        return sqlSession.selectOne("com.multi.erp.board.getfile", inputdata);
    }
}

 

 

board.xml
<select id="getfile" resultType="boardfile" parameterType="boardfile">
    select * from board_file where board_no = #{board_no} and boardFileno = #{boardFileno}
</select>

 

 

 

 

BoardController

 

HttpEntity의 하위 객체인 ResponseEntity클래스와 UrlResource클래스를 이용.

 

HttpEntity : Http요청과 응답을 관리하는 객체로 요청헤더/바디, 응답헤더/바디를 관리

ResponseEntity : 응답데이터를관리하는 객체(Http헤어, Http바디, Http상태정보 ...)

UrlResource : 파일객체를 다루기 위해서 스프링 내부에서 사용하는 객체

 

@RequestMapping("/board/download/{id}/{board_no}/{boardFileno}")
	public ResponseEntity<UrlResource> downloadFile(@PathVariable String id, @PathVariable String board_no, 
						@PathVariable String boardFileno, HttpSession session) {
	BoardFileDTO selectFileInfo = service.getFile(new BoardFileDTO(board_no, "", "", boardFileno));
	UrlResource resource = new UrlResource("file:"+WebUtils.getRealPath(session.getServletContext(),
						"/WEB-INF/upload/"+selectFileInfo.getStoreFilename()));
	String encodedFilename = UriUtils.encode(selectFileInfo.getOriginalFilename(), "utf-8");
	String mycontenttype = "attachment; filename=\"" + encodedFilename + "\"";
	return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, mycontenttype) 
				  .body(resource);

 

이전 파일업로드 게시글에서 사용자의 사원아이디(id)와 글번호(board_no), 파일번호(boardFileno)로 첨부파일을 구분해 뒀으니 이제 글번호와 파일번호를 이용해 특정 파일을 다운받아보자.

 

 

 

① 파일을 다운로드 하기 위해서 db에 저장된 파일의 정보를 가져오기

다운로드를 요청한 경우 요청된 파일을 response한다.

글번호와 파일번호를 이용해서 해당 파일을 조회 => 요청한 파일에 대한 조회이므로 BoardFileDTO를 리턴하도록 처리

 

BoardFileDTO selectFileInfo = service.getFile(new BoardFileDTO(board_no, "", "", boardFileno));

요청한 파일에 대한 조회이므로 BoardFileDTO를 리턴

 

 

 

② 파일명을 이용해서 다운로드할 파일을 객체로 생성하기

// 형식 : UrlResource resource = new UrlResource("file:"+파일의 풀 경로);
UrlResource resource = new UrlResource("file:"+WebUtils.getRealPath(session.getServletContext(),
					"/WEB-INF/upload/"+selectFileInfo.getStoreFilename()));

 

WebUtil : 실제 서버가 인식하는 경로를 추출하기 위해 사용하는 클래스  (설명)

서버가 인식하는 위치에, 서버에 저장된 파일이름(유저가 저장한 이름X) 입력

 

 

 

③ 파일명에 한글이 있는 경우 오류가 발생하지 않도록 처리하기 - 다운로드되는 파일명 지정

String encodedFilename = UriUtils.encode(selectFileInfo.getOriginalFilename(), "utf-8");
String mycontenttype = "attachment; filename=\"" + encodedFilename + "\"";

selectFileInfo → DB에서 받아온 파일데이터

1) 한글이 깨질 수 있기 때문에 UriUtils클래스를 이용해 인코딩 하기. 

2) CONTENT_DISPOSITION속성에 셋팅할 문자열의 형식으로 이 형식으로 지정해야 파일다운로드를 할 수 있다.

다운로드 되는 파일명 = 유저가 첨부파일로 등록한 이름

 

 

 

④ 파일 다운로드

return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, mycontenttype)
	  		  .body(resource);

.ok() → 정상응답이라는 의미이며, ok는 http응답의 헤더와 바디를 만들 수 있는 객체인 BodyBuilder를 리턴함

.header의 " HttpHeaders.CONTENT_DISPOSITION "은 Body에 오는 컨텐츠의 내용을 알려주는 속성이다(지금은 파일다운로드 하는 작업이야 하고 알려주는 역할~). 

.body → body에 다운로드 할 파일을 담아보냄

( resource : 다운로드할 파일 객체로 생성해서 담은 변수 )

 

 

 

board_read.jsp
<a href="/erp/board/download/
${board.id}/${board.board_no}/${file.boardFileno}">${file.originalFilename}</a>

기존에 했던 방식으로도 가능 → [ board/download?board_no=${board.board_no}&state="READ" ]

 

+ 컨트롤러에서는 파라미터를 아래의 방식으로 표현해준다.

downloadFile(@PathVariable String id, @PathVariable String board_no, 
		@PathVariable String boardFileno, HttpSession session)

댓글