[Spring 20-1] 파일 업로드 방법 - 테이블 업로드 O

임승현·2023년 3월 7일

Spring

목록 보기
46/46

🌈테이블 만들기

create table fileboard(num number primary key, writer varchar2(20)
    , subject varchar2(100), origin varchar2(100), upload varchar2(100));
create sequence fileboard_seq;

🌈DTO 클래스 생성

📃FileBoard.java

※ xyz.itwill10.dto 패키지에 FileBoard.java 클래스 생성

package xyz.itwill10.dto;
//
import org.springframework.web.multipart.MultipartFile;
import lombok.Data;
/*
이름      널?       유형            
------- -------- ------------- 
NUM     NOT NULL NUMBER        	- 글번호
WRITER           VARCHAR2(20)  	- 작성자
SUBJECT          VARCHAR2(100) 	- 제목
ORIGIN           VARCHAR2(100) 	- 원본 파일명
UPLOAD           VARCHAR2(100)	- 업로드 파일명(서버 디렉토리에 저장되는 파일명)
*/
//
//DTO 클래스 >> 전달값을 제공받아 사용하기 위한 Command 객체의 클래스
//
@Data
public class FileBoard {
	private int num;
	private String writer;
	private String subject;
	private String origin;
	private String upload;
	private MultipartFile file;//전달파일을 저장하기 위한 필드
}

🌈매퍼 파일 생성

📃FileBoardMapper.xml

※ xyz.itwill10.mapper 패키지에 FileBoardMapper.xml 파일 생성

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill10.mapper.FileBoardMapper">
	<!-- =============================================================================================== -->
	<insert id="insertFileBoard">
		<selectKey resultType="int" keyProperty="num" order="BEFORE">
			select fileboard_seq.nextval from dual		
		</selectKey>
		insert into fileboard values(#{num},#{writer},#{subject},#{origin},#{upload})
	</insert>
	<!-- =============================================================================================== -->
	<delete id="deleteFileBoard">
		delete from fileboard where num=#{num}
	</delete>
	<!-- =============================================================================================== -->
	<select id="selectFileBoard" resultType="FileBoard">
		select * from fileboard where num=#{num}
	</select>
	<!-- =============================================================================================== -->
	<select id="selectFileBoardList" resultType="FileBoard">
		select * from fileboard order by num desc
	</select>
</mapper>

📃FileBoardMapper.java(인터페이스)

※ xyz.itwill10.mapper 패키지에 FileBoardMapper.java 인터페이스 파일 생성

package xyz.itwill10.mapper;
//
import java.util.List;
import xyz.itwill10.dto.FileBoard;
//
public interface FileBoardMapper {
	int insertFileBoard(FileBoard fileBoard);
	int deleteFileBoard(int num);
	FileBoard selectFileBoard(int num);
	List<FileBoard> selectFileBoardList();
}

🌈DAO 클래스 생성

📃FileBoardDAO.java(인터페이스)

※ xyz.itwill10.dao 패키지에 FileBoardDAO.java 인터페이스 생성

package xyz.itwill10.dao;
//
import java.util.List;
import xyz.itwill10.dto.FileBoard;
//
public interface FileBoardDAO {
	int insertFileBoard(FileBoard fileBoard);
	int deleteFileBoard(int num);
	FileBoard selectFileBoard(int num);
	List<FileBoard> selectFileBoardList();
}

📃FileBoardDAOImpl.java

※ xyz.itwill10.dao 패키지에 FileBoardDAOImpl.java 클래스 생성

package xyz.itwill10.dao;
//
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dto.FileBoard;
import xyz.itwill10.mapper.FileBoardMapper;
//
@Repository
@RequiredArgsConstructor
public class FileBoardDAOImpl implements FileBoardDAO {
	private final SqlSession sqlSession;
	//
	@Override
	public int insertFileBoard(FileBoard fileBoard) {
		return sqlSession.getMapper(FileBoardMapper.class).insertFileBoard(fileBoard);
	}
	@Override
	public int deleteFileBoard(int num) {
		return sqlSession.getMapper(FileBoardMapper.class).deleteFileBoard(num);
	}
	@Override
	public FileBoard selectFileBoard(int num) {
		return sqlSession.getMapper(FileBoardMapper.class).selectFileBoard(num);
	}
	@Override
	public List<FileBoard> selectFileBoardList() {
		return sqlSession.getMapper(FileBoardMapper.class).selectFileBoardList();
	}
}

🌈Service 클래스 생성

📃FileBoardService.java(인터페이스)

※ xyz.itwill10.service 패키지에 FileBoardService.java 인터페이스 파일 생성

package xyz.itwill10.service;
//
import java.util.List;
import xyz.itwill10.dto.FileBoard;
//
public interface FileBoardService {
	void addFileBoard(FileBoard fileBoard);
	void removeFileBoard(int num);
	FileBoard getFileBoard(int num);
	List<FileBoard> getFileBoardList();
}

📃FileBoardServiceImpl.java

※ xyz.itwill10.service 패키지에 FileBoardServiceImpl.java 클래스 생성

package xyz.itwill10.service;
//
import java.util.List;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dao.FileBoardDAO;
import xyz.itwill10.dto.FileBoard;
//
@Service
@RequiredArgsConstructor
public class FileBoardServiceImpl implements FileBoardService {
	private final FileBoardDAO fileBoardDAO; 
	//
	@Override
	public void addFileBoard(FileBoard fileBoard) {
		fileBoardDAO.insertFileBoard(fileBoard);
	}
	@Override
	public void removeFileBoard(int num) {
		fileBoardDAO.deleteFileBoard(num);
	}
	@Override
	public FileBoard getFileBoard(int num) {
		return fileBoardDAO.selectFileBoard(num);
	}
	@Override
	public List<FileBoard> getFileBoardList() {
		return fileBoardDAO.selectFileBoardList();
	}
}

🌈Controller 클래스 수정(19-1의 컨트롤러 클래스에 코드 작업)

📃FileController.java

※ xyz.itwill10.controller 패키지에 FileController.java 클래스 생성

package xyz.itwill10.controller;
//
import java.io.File;
import java.io.IOException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.MultipartFile;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dto.FileBoard;
import xyz.itwill10.service.FileBoardService;
//
//파일 업로드 처리를 위한 환경설정 방법
//1.commons-fileupload 라이브러리를 프로젝트에 빌드 처리 - 메이븐 : pom.xml
//2.Spring Bean Configuration File(servlet-context.xml)에 파일 업로드 기능을 제공하는 클래스를 Spring Bean으로 등록
//3.MultipartHttpServletRequest 객체를 사용하여 [multipart/form-data] 형태로 전달된 값 또는 파일 처리
//
@Controller
@RequiredArgsConstructor
public class FileController {
	//WebApplicationContext 객체(Spring Container)를 제공받아 필드에 의존성 주입
	private final WebApplicationContext context;
	private final FileBoardService fileBoardService;//테이블 연동
	//
	@RequestMapping(value = "/upload", method = RequestMethod.GET)
	public String upload() {
		return "file/upload_form";
	}
	/*
	//요청 처리 메소드에 MultipartHttpServletRequest 인터페이스로 매개변수를 선언하면 Front Controller에 의해 MultipartHttpServletRequest 객체를 제공받아 사용 가능
	//MultipartHttpServletRequest 객체 : [multipart/form-data] 형식으로 전달된 값 또는 파일을 처리하기 위한 객체
	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	public String upload(MultipartHttpServletRequest request) throws IOException {
		//MultipartHttpServletRequest.getParameter(String name) : [multipart/form-data] 형식으로 전달된 값을 문자열(String 객체)로 반환하는 메소드
		String uploaderName=request.getParameter("uploaderName");
		//
		//MultipartHttpServletRequest.getFile(String name) : [multipart/form-data] 형식으로 전달된 파일을 MultipartFile 객체로 반환하는 메소드
		//MultipartFile 객체 : 사용자로부터 입력되어 전달된 파일정보를 저장하기 위한 객체
		MultipartFile uploadFile=request.getFile("uploadFile");
		//
		//전달받은 파일에 대한 검증 작업
		//MultipartFile.isEmpty() : MultipartFile 객체에 파일정보가 없는 경우 [false]를 반환하고 파일정보가 있는 경우 [true]를 반환하는 메소드
		if(uploadFile.isEmpty()) {
			return "file/upload_fail";
		}
		//
		//MultipartFile.getContentType() :  MultipartFile 객체에 저장된 파일의 형식(MimeType)를 반환하는 메소드 
		System.out.println("파일 형식 = "+uploadFile.getContentType());
		//MultipartFile.getBytes() : MultipartFile 객체에 저장된 파일정보를 byte 배열로 반환하는 메소드
		System.out.println("파일 크기 = "+uploadFile.getBytes().length);
		//
		//전달파일을 저장하기 위한 서버 디렉토리의 시스템 경로를 반환받아 저장
		String uploadDirectory=request.getServletContext().getRealPath("/resources/images/upload");
		System.out.println("uploadDirectory = "+uploadDirectory);
		//
		//전달파일을 서버 디렉토리에 저장하기 위한 File 객체 생성
		//File 객체 : 시스템에 존재하는 파일정보를 저장하기 위한 객체
		//MultipartFile.getOriginalFilename() : 전달파일의 파일명을 반환하는 메소드
		File file=new File(uploadDirectory, uploadFile.getOriginalFilename());
		//
		//MultipartFile.transferTo(File file) : MultipartFile 객체에 저장된 파일정보를 File 객체에 저장된 파일정보로 전달하여 저장하는 메소드 - 업로드 처리 메소드
		uploadFile.transferTo(file);
		//
		request.setAttribute("uploaderName", uploaderName);
		request.setAttribute("uploadFilename", uploadFile.getOriginalFilename());
		//
		return "file/upload_ok";
	}
	*/
	//
	//요청 처리 메소드에 매개변수를 작성하여 전달값과 전달파일을 제공받아 사용 가능
	//→ 업로드 파일과 같은 이름의 파일이 서버 디렉토리에 존재할 경우 기존 파일 대신 업로드
	//파일이 저장 - 덮어씌위기(OverWrite)
	//→ commons-fileupload 라이브러리에는 업로드 파일을 변경하는 기능의 클래스 미존재
	//→ 업로드 파일과 같은 이름의 파일이 서버 디렉토리에 존재할 경우 업로드 파일명을 변경하는 명령 작성 필요
	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	public String upload(@RequestParam String uploaderName
			, @RequestParam MultipartFile uploadFile, Model model) throws IOException {
		if(uploadFile.isEmpty()) {
			return "file/upload_fail";
		}
		//
		//전달파일을 저장하기 위한 서버 디렉토리의 시스템 경로를 반환받아 저장
		//→ WebApplicationContext 객체(Spring Container)에게 ServletContext 객체를 제공받아 사용
		String uploadDirectory=context.getServletContext().getRealPath("/resources/images/upload");
		//
		//사용자로부터 입력되어 전달된 원본 파일명을 반환받아 저장
		String originalFilename=uploadFile.getOriginalFilename();
		//
		//서버 디렉토리에 저장하기 위한 파일정보가 저장된 File 객체 생성
		File file=new File(uploadDirectory, originalFilename);
		//
		//서버 디렉토리에 저장될 파일명을 저장하기 위한 변수
		//→ 초기값으로 사용자로부터 입력되어 전달된 원본 파일명을 저장
		String uploadFilename=originalFilename;
		//
		//업로드 파일과 같은 이름의 파일이 서버 디렉토리에 존재할 경우 서버 디렉토리에 저장될 파일명을 구분하기 위한 식별자를 저장하기 위한 변수
		int i=0;
		//
		//File.exists() : File 객체에 저장된 파일이 시스템이 존재하지 않을 경우 [false]를 반환하고 존재할 경우 [true]를 반환하는 메소드
		while(file.exists()) {//업로드 파일과 같은 이름의 파일이 서버 디렉토리에 존재할 경우 반복 처리
			i++;
			//
			//파일명과 확장자를 구분하기 위한 문자열(.)를 사용하여 위치값(Index)을 반환받아 저장
			int index=originalFilename.lastIndexOf(".");
			//
			//원본 파일명을 이용하여 업로드 파일명 생성
			uploadFilename=originalFilename.substring(0, index)+"_"+i+originalFilename.substring(index);
			//
			//서버 디렉토리에 저장될 파일명을 저장하기 위한 변수
			file=new File(uploadDirectory, uploadFilename);
		}
		//
		uploadFile.transferTo(file);
		//
		model.addAttribute("uploaderName", uploaderName);
		model.addAttribute("originalFilename", originalFilename);
		model.addAttribute("uploadFilename", uploadFilename);
		//
		return "file/upload_ok";
	}
	//============================================================================================================================
	//테이블 연동
	@RequestMapping(value = "/fileboard/write", method = RequestMethod.GET)
	public String fileBoardWrite() {
		return "file/board_write";
	}
	//
	//매개변수를 작성하여 모든 전달값과 전달파일을 Command 객체로 제공받아 사용 가능
	@RequestMapping(value = "/fileboard/write", method = RequestMethod.POST)
	public String fileBoardWrite(@ModelAttribute FileBoard fileBoard) throws IllegalStateException, IOException {//전달값을 반환받아 저장
		if(fileBoard.getFile().isEmpty()) {
			return "file/board_write";
		}
		//
		//전달파일이 저장될 서버 디렉토리의 시스템 경로를 반환받아 저장
		//→ 다운로드 프로그램에서만 파일에 접근 가능하도록 /WEB-INF 폴더에 업로드 폴더 생성
		String uploadDir=context.getServletContext().getRealPath("/WEB-INF/upload");//파일을 저장할 경로를 지정
		//
		//사용자로부터 입력받아 전달된 원본파일의 이름을 반환받아 저장
		String origin=fileBoard.getFile().getOriginalFilename();
		//
		//서버 디렉토리에 저장된 업로드 파일명을 생성하여 저장
		//→ 업로드 파일명은 서버 디렉토리에 존재하는 파일명과 중복되지 않도록 고유값 사용
		//→ 업로드 파일명은 시스템의 현재 날짜와 시간에 대한 정수값(TimeStamp)를 사용하여 작성
		String upload=System.currentTimeMillis()+"";
		//
		//Command 객체(FileBoard 객체)의 필드값 변경
		fileBoard.setOrigin(origin);
		fileBoard.setUpload(upload);
		//
		//파일 업로드 처리
		fileBoard.getFile().transferTo(new File(uploadDir, upload));//에러 떠넘기기
		//
		//FILEBOARD 테이블에 행 삽입
		fileBoardService.addFileBoard(fileBoard);
		//
		return "redirect:/fileboard/list";
	}
	//
	@RequestMapping("/fileboard/list")
	public String fileBoardList(Model model) {
		model.addAttribute("fileBoardList", fileBoardService.getFileBoardList());
		return "/file/board_list";
	}
	//
	//URL 주소로 전달된 값을 @PathVariable 어노테이션을 사용하여 매개변수로 제공받아 사용
	@RequestMapping("/fileboard/delete/{num}")
	public String fileBoardDelete(@PathVariable int num) {
		FileBoard fileBoard=fileBoardService.getFileBoard(num);
		String uploadDir=context.getServletContext().getRealPath("/WEB-INF/upload");
		//서버 디렉토리에 저장된 업로드 파일을 삭제 처리
		new File(uploadDir, fileBoard.getUpload()).delete();
		fileBoardService.removeFileBoard(num);
		return "redirect:/fileboard/list";
	}
	//
	//다운로드(Download) : 서버 디렉토리에 존재하는 파일을 클라이언트에 전달하여 저장하는 기능 요청 처리 메소드에 의해 
	//	반환되는 문자열(ViewName)으로 다운로드 프로그램을 실행하여 서버 디렉토리에 저장된 파일을 클라이언트에게 전달하여 응답 처리
	//→ BeanNameViewResolver 객체를 사용하여 반환하는 문자열로 특정 프로그램 실행
	//→ Spring Bean Configuration File(servlet-context.xml)에 BeanNameViewResolver 클래스를 Spring Bean으로 등록
	//현재 사용중인 ViewResolver 객체는 요청 처리 메소드에서 반환되는 문자열을 이용해 JSP 문서로 응답되도록 처리
	//→ UrlBasedViewResolver(TilesView), InternalResourceViewResolver
	@RequestMapping("/fileboard/download/{num}")
	public String fileBoardDownload(@PathVariable int num, Model model) {
		FileBoard fileBoard=fileBoardService.getFileBoard(num);
		//
		//Model 객체를 이용하여 실행될 프로그램(Spring Bean)에서 사용하기 위한 객체를 속성값으로 저장하여 제공
		model.addAttribute("uploadDir", context.getServletContext().getRealPath("/WEB-INF/upload"));
		model.addAttribute("uploadFilename",fileBoard.getUpload());
		model.addAttribute("originalFilename",fileBoard.getOrigin());
		//
		//실행될 프로그램(Spring Bean)의 식별자(beanName)를 반환
		//→ 실행될 프로그램에 대한 클래스를 작성하여 Spring Bean Configuration File
		//(servlet-context.xml)에 Spring Bean으로 등록
		return "fileDownload";
	}
}

🌈JSP 작성

📃board_write.jsp

※ WEB-INF/views/rest 폴더에 board_write.jsp 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
	<h1>자료실(입력페이지)</h1>
	<hr>
	<form method="post" enctype="multipart/form-data">
	<table>
		<tr>
			<td>작성자</td>
			<td><input type="text" name="writer"></td>
		</tr>
		<tr>
			<td>제목</td>
			<td><input type="text" name="subject"></td>
		</tr>
		<tr>
			<td>파일</td>
			<td><input type="file" name="file"></td>
		</tr>
		<tr>
			<td colspan="2"><button type="submit">파일전송</button></td>
		</tr>
	</table>
	</form>
</body>
</html>

📃board_list.jsp

※ WEB-INF/views/rest 폴더에 board_write.jsp 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
<style type="text/css">
table {
	border: 1px solid black;
	border-collapse: collapse;
}
th, td {
	border: 1px solid black;
	padding: 2px;
}
</style>
</head>
<body>
	<h1>자료실(출력페이지)</h1>
	<hr>
	<table>
		<tr>
			<th width="50">번호</th>
			<th width="100">작성자</th>
			<th width="300">제목</th>
			<th width="350">파일명</th>
			<th width="100">다운로드</th>
			<th width="100">삭제</th>
		</tr>
		<c:forEach var="fileBoard" items="${fileBoardList }">
		<tr>
			<td align="center">${fileBoard.num }</td>
			<td align="center">${fileBoard.writer }</td>
			<td>${fileBoard.subject }</td>
			<td>${fileBoard.origin }</td>
			<td align="center">
				<button type="button" onclick="fileDownload(${fileBoard.num });">다운로드</button> 
			</td>
			<td align="center">
				<button type="button" onclick="fileDelete(${fileBoard.num });">삭제</button> 
			</td>
		</tr>
		</c:forEach>
	</table>
	<p>
		<button type="button" onclick="location.href='${pageContext.request.contextPath}/fileboard/write';">업로드</button>
	</p>
	<!-- 다운로드 관련 함수 -->
	<script type="text/javascript">
	function fileDownload(num) {
		//URL 주소를 이용하여 자료실 번호 전달
		location.href="${pageContext.request.contextPath}/fileboard/download/"+num;
	}
	<!-- 삭제 관련 함수 -->
	function fileDelete(num) {
		if(confirm("자료를 정말로 삭제 하시겠습니까?")) {
			location.href="${pageContext.request.contextPath}/fileboard/delete/"+num;
		}
	}
	</script>
</body>
</html>

🌈파일 다운로드 관련 클래스 생성

📃FileDownload.java

※ xyz.itwill10.util 패키지에 FileDownload.java 클래스 생성

package xyz.itwill10.util;
//
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.view.AbstractView;
//
//파일 다운로드 기능을 제공하기 위한 클래스 - BeanNameViewResolver 객체에 의해 실행되는 클래스
//→ Spring Bean Configuration File(servlet-context.xml)에 Spring Bean으로 등록
//BeanNameViewResolver 객체에 의해 실행되는 클래스는 반드시 AbstractView 클래스를 상속받아 작성
//→ renderMergedOutputModel() 메소드를 오버라이드 선언하여 응답에 필요한 명령 작성
public class FileDownload extends AbstractView {
	//클라이언트에게 응답될 파일형식(MimeType)에 대한 변경 - 파일 다운로드 기능
	public FileDownload() {
		//AbstractView.setContentType(String mimeType) : 응답 파일 형식을 변경하는 메소드
		setContentType("application/download; utf-8");
	}
	//
	//BeanNameViewResolver 객체에 의해 자동 호출되는 메소드
	//→ Map 자료형의 매개변수에는 요청 처리 메소드에서 제공된 속성값이 엔트리로 저장된 Map 객체 제공
	@Override
	protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		//요청 처리 메소드에서 제공된 속성값(파일 관련 정보)을 객체로 반환받아 저장
		String uploadDir=(String)model.get("uploadDir");
		String uploadFilename=(String)model.get("uploadFilename");
		String originalFilename=(String)model.get("originalFilename");
		//
		//서버 디렉토리에 저장된 다운로드 파일에 대한 File 객체 생성
		File downloadFile=new File(uploadDir, uploadFilename);
		//
		//클라이언트에게 파일을 전달하기 위해 리스폰즈 메세지의 머릿부 변경
		response.setContentType(getContentType());
		response.setContentLengthLong((int)downloadFile.length());
		//
		//다운로드 처리되어 클라이언트에 저장되 파일명을 리스폰즈 메세지의 머릿부에 저장하여 전달
		//→ 파일명에 대한 한글 문제로 인해 부호화 처리하여 전달
		originalFilename=URLEncoder.encode(originalFilename, "utf-8");
		response.setHeader("Content-Disposition","attachement;filename=\""+originalFilename+"\";");
		//
		//리스폰즈 메세지 몸체부에 파일을 전달하여 저장하기 위한 출력스트림을 반환받아 저장
		OutputStream out=response.getOutputStream();
		//
		//서버 디렉토리에 저장된 다운로드 파일을 읽기 위한 입력스트림을 생성하여 저장
		InputStream in=new FileInputStream(downloadFile);
		//
		//FileCopyUtils.copy(InputStream in, OutputStream out) : 입력스트림으로 원시데이타를 반복적으로 읽어 출력스트림으로 전달하는 메소드 - 파일 복사 
		FileCopyUtils.copy(in, out);
		//
		in.close();
	}
}

🌈환경설정 파일 수정

📃servlet-context.xml

<!-- BeanNameViewResolver 클래스를 Spring Bean으로 등록 -->
<!-- BeanNameViewResolver : 요청 처리 메소드에서 반환되는 문자열(ViewName)을 제공받아 
	같은 이름(beanName)의 객체(Spring Bean)의 실행 메소드를 호출하여 클라이언트에게 응답 -->
<!-- → JSP 문서를 이용하여 응답하지 않고 메소드의 명령을 실행하여 응답 처리 -->
<!-- → 반드시 JSP 문서로 응답되는 ViewResolver 객체로바 우선순위를 높도록 설정 -->
<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
	<beans:property name="order" value="1"/>
</beans:bean>
<!-- BeanNameViewResolver 객체에 의해 실행될 클래스를 Spring Bean으로 등록 -->
<!-- → 요청 처리 메소드의 반환값(ViewName)과 Spring Bean의 식별자(beanName)이 같아야 Front Controller에 의해 객체의 실행 메소드를 호출하여 응답 처리 -->
<beans:bean class="xyz.itwill10.util.FileDownload" id="fileDownload"/>

0개의 댓글