728x90

이전 포스팅인 게시판 파일 업로드 예제에 이어서

이번에는 파일을 다운로드 하는 예제를 진행해보겠다.

 

따라서 DB 내에 게시글 테이블 및 파일 정보 테이블이 존재하고,

파일 업로드 예제의 소스코드가 작성되어 있다고 가정한다.

 

이전 포스팅 참고


https://just-joat.tistory.com/34

 

[Spring Boot] 스프링부트 & MyBatis 게시판 파일 업로드 예제

기존에 게시판의 기본적인 생성, 조회 등의 기능은 구현되어 있다는 가정하에 진행하겠다. ※ 개발환경프레임워크: Spring Boot 2.7.12DB: MyBatis, MyBatisJava: JDK 1.8템플릿 엔진: Thymeleaf  1. DB 설계기존

just-joat.tistory.com

 

 

파일을 다운로드 하기 위해서는 먼저, 게시글 상세 페이지에서 

해당 게시글의 파일이 보여아 한다.

 

 

1. FileResponse 클래스 생성


@Getter
@ToString
public class FileResponse {
	
	private int seq;
	private int boardSeq;
	private String originalName;
	private String saveName;
	private long size;
	private String deleteYn;
	private Timestamp createdDate;
	private Timestamp deletedDate;
}
  • DB에 저장된 파일 테이블을 통해 파일정보를 클라이언트에게 응답해주기 위한 응답용 객체이다.

 

 

2. FileMapper 인터페이스 수정 - 게시글에 등록된 파일 조회 메서드 추가


@Mapper
public interface FileMapper {
	void saveAll(List<FileRequest> files); // 파일 정보 저장
	
	List<FileResponse> getFilesByBoardSeq(int boardSeq); // 게시글 파일 리스트 조회
}
  • List<FileResponse> getFilesByBoardSeq(int boardSeq): 게시글 기본키인 boardSeq 값을 참조하여 파일 테이블 내 해당 게시글의 파일들의 정보를 조회하는 메서드
  • 리턴 타입은 방금 생성한 FileResponse 클래스로 지정한다.

 

 

3. FileMapper 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="com.example.file.service.FileMapper">

	<sql id="fileColumns">
		BOARD_SEQ
		, ORIGINAL_NAME
		, SAVE_NAME
		, SIZE
		, DELETE_YN
		, CREATED_DATE
		, DELETED_DATE
	</sql>
	
	<insert id="saveAll" parameterType="List">
		INSERT INTO BOARD_FILE (
			<include refid="fileColumns"></include>
		) VALUES
		<foreach item="file" collection="files" separator=",">
		(
			#{file.boardSeq}
			, #{file.originalName}
			, #{file.saveName}
			, #{file.size}
			, 'N'
			, NOW()
			, NULL		
		)
		</foreach>
	</insert>
	
    <!-- getFilesByBoardSeq 조회 결과 테이블을 FileResponse 객체와 매핑 -->
    <resultMap type="egovframework.example.file.dto.FileResponse" id="fileResponse">  
		<result property="seq" column="SEQ"/>
		<result property="boardSeq" column="BOARD_SEQ"/>
		<result property="originalName" column="ORIGINAL_NAME"/>
		<result property="saveName" column="SAVE_NAME"/>
		<result property="size" column="SIZE"/>
		<result property="deleteYn" column="DELETE_YN"/>
		<result property="createdDate" column="CREATED_DATE"/>
		<result property="deletedDate" column="DELETED_DATE"/>
	</resultMap>
    
    <select id="getFilesByBoardSeq" resultMap="fileResponse"> <!-- 게시글 파일 조회 기능 추가 -->
		SELECT 
			SEQ,
			<include refid="fileColumns"></include>
		FROM
			BOARD_FILE
		WHERE
			DELETE_YN = 'N'
			AND BOARD_SEQ = #{boardSeq}
	</select>

</mapper>
  • 앞서 생성한 Mapper 인터페이스의 getFilesBoardSeq() 메서드와 연결할 쿼리를 작성한다.
  • 게시글 테이블의 기본키인 BOARD_SEQ 칼럼을 참조하여 해당 게시글의 해당되는 파일들을 조회한다. 
  • 조회 결과를 FileResponse 객체로 변환하여야 하기 때문에 ResultMap 태그를 작성해준다.

 

 

4. FileService 클래스 수정 - 게시글에 등록된 파일 조회 메서드 추가


public List<FileResponse> getFilesByBoardSeq(int boardSeq) { // 파일 정보 조회
    return fileMapper.getFilesByBoardSeq(boardSeq);
}
  • Mapper 인터페이스를 통해 XML 쿼리까지 연결되기 위해 FileService 클래스에도 메서드를 추가해준다.

 

 

5. FileRestController 클래스 생성


@RestController
@RequiredArgsConstructor
public class FileRestController {
	
	private final FileService fileService;
	
	@GetMapping("/fileList")
	public ResponseEntity<Object> getFileList(@RequestParam("boardSeq") int seq) {
		List<FileResponse> files = new ArrayList<>();

		files = fileService.getFilesByBoardSeq(seq);
		
		return ResponseEntity.status(HttpStatus.OK).body(files);

	}
}
  • 파일 정보 조회 요청을 받을 컨트롤러를 생성한다.
  • 해당 컨트롤러는 API 형식으로 통신이 진행될 것이기 때문에 @RestController 어노테이션을 지정해준다.
  • ResponseEntity 객체를 통해 게시글의 파일들의 정보를 JSON 형태로 리턴한다.

 

 

6. 게시글 상세 페이지 HTML 수정 - 게시글 파일 정보 영역 및 AJAX 통신 함수 추가


            <tr>
                <td>첨부파일</td>
                <td id="files"></td>
            </tr>
  • 다음과 같이 게시글 상세 페이지에 파일 정보가 보이게 될 영역을 추가한다

    window.onload = () => { // 상세 페이지가 로드되면 파일정보 조회 API 실행
        getFiles();
    }

    function getFiles() { // AJAX 통신을 통해 파일정보를 불러옴.
        let seq = [[${board.seq}]] || '';
        $.ajax({
            type: 'get',
            url: `/fileList?boardSeq=${seq}`,
            success: function(result) {
                console.log(result);
                setFileInfo(result)
            }
        })
    }

    function setFileInfo(files) { // HTML 내 파일영역에 불러온 파일정보 삽입
        let fileHtml = '<div class="file_down"><div class="cont">';
        files.forEach(row => {
            fileHtml += `<a>${row.originalName}</a>`
        })

        fileHtml += '</div></div>'

        document.getElementById('files').innerHTML = fileHtml
    }
  • 게시글 상세 페이지가 로드되면 getFiles() -> setFileInfo() 함수가 순서대로 실행된다.
  • getFiles(): AJAX를 통해 FileController에 파일 정보를 요청한다.
  • setFileInfo(): AJAX 요청이 성공하면 응답받은 파일 정보를 HTML 내 파일 영역에 삽입된다. 

 

 

※ 결과


춘식이.png가 잘 보인다.

 

 

파일 다운로드 기능은 다음 포스팅에서 다루겠다.

728x90