첨부파일
CommonController
- uploadPath 경로 가져오기
- 파일 확장자 체크 변수
- 파일 업로드 메소드
- 파일 다운로드 메소드
업로드/다운로드 구현하기 전에, pom.xml에 파일 업로드 라이브러리를 추가한다.
<!-- 파일업로드 라이브러리 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
또한, servlet-context.xml에 아래 코드를 추가한다.
- uploadPath는 파일이 업로드/다운로드되는 경로이다.
<!-- html폼에서 첨부파일 업로드 설정 10메가 제한 -->
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="10485760"></beans:property>
</beans:bean>
<!-- 업로드한 파일이 저장되는 위치: 로컬PC용 -->
<beans:bean id="uploadPath" class="java.lang.String">
<beans:constructor-arg value="C:\\egov\\workspace\\upload" />
</beans:bean>
사전 설정이 끝났다.
1. 파일 업로드 구현 (CommonController.java)
- 첨부파일의 확장자를 확인하는 변수를 생성한다.
- 첨부파일 확장자를 확인하여, 이미지일 때 미리보기 가능, 아니라면 그냥 파일명만 보이게.
private ArrayList<String> extNameArray = new ArrayList<String>() {
{
add("gif");
add("jpg");
add("jpeg");
add("png");
add("bmp");
}
};
public ArrayList<String> getCheckImgArray() {
return checkImgArray;
}
public void setCheckImgArray(ArrayList<String> checkImgArray) {
this.checkImgArray = checkImgArray;
}
- 파일을 업로드할 경로를 가져온다.
- 아래 경로는 servlet-context.xml에 빈으로 등록되어있는 uploadPath에서 가져온다.
@Resource(name="uploadPath")
private String uploadPath;
public String getUploadPath() {
return uploadPath;
}
public void setUploadPath(String uploadPath) {
this.uploadPath = uploadPath;
}
- 파일 업로드를 구현할 메소드를 생성한다.
- servlet-context.xml에 지정한 폴더에 실제 파일을 저장하도록 구현
public String[] fileUpload(MultipartFile file) throws IOException {
String realFileName = file.getOriginalFilename(); //jsp에서 전송한 파일명 -> 확장자 구할 때 사용
//만약 파일이 여러개면 아래 부분에 변수 처리 로직이 더 들어가야 한다.
//폴더에 저장할 PK용 파일명 만들기(아래)
UUID uid = UUID.randomUUID(); //unique id 생성 : 폴더에 저장할 파일명으로 사용
//String saveFileName = uid.toString()+"."+realFileName.split("\\.")[1]; //문제발생하여 아래코드로 대체
String saveFileName = uid.toString()+"."+StringUtils.getFilenameExtension(realFileName);
//realFileName.split("\\."); realFileName을 .으로 분할해서 파일변수로 만드는 메소드
//ex. abc.jpg -> realFileName[0]=abc, realFileName[1]=jpg
String[] files = new String[] {saveFileName}; //saveFileName 스트링형을 배열변수 files로 형변환
byte[] fileData = file.getBytes(); //jsp폼에서 전송된 파일이 fileData변수(메모리)에 저장된다.
//uploadPath경로의 saveFileName이름을 가진 파일이 타겟이 된다.
File target = new File(uploadPath,saveFileName); //파일 저장하기 바로 전 설정 저장
FileCopyUtils.copy(fileData, target); //실제로 target폴더에 파일로 저장되는 메소드 = 업로드끝
return files; // 1개 이상의 파일 업로드 시, 저장된 파일명을 배열로 저장한 변수
//첨부파일이 한개 이상일 수 있기 때문에, BoardVO에 save_file_names가 배열형이기 때문에.
}
- jsp에서 전송한 실제 파일명을 realFileName 변수에 저장한다.
- unique id를 랜덤으로 생성하여 uid 변수에 저장한다.
- 생성한 uid + realFileName의 확장자를 saveFileName 변수에 저장한다.
- saveFileName을 files 배열 변수에 반환한다.
- jsp 폼에서 전송된 파일이 fileData변수(메모리)에 저장한다.
- File 클래스형 target 변수에 uploadPath 경로의 saveFileName라는 이름을 가진 파일을 저장한다.
- FileCopyUtils 메소드를 사용하여 target 파일에 fileData 내용을 복사한다. = 업로드 끝
FileCopyUtils.copy(File in, File out)
- 지정한 입력 File내용을 지정한 출력 File에 복사한다. 리턴값은 복사한 byte수.
- 업로드 후, files 반환(saveFileName 저장되어있는 배열 변수)
- BoardVO에 저장 파일 이름과 실제 파일 이름을 저장할 멤버변수를 생성한다.
private String[] save_file_names; // 폴더에 저장되는 실제파일명을 배열형으로 변경할 때 사용한 변수
private String[] real_file_names; // DB에 저장되는 한글파일명을 배열형으로 변경할 때 사용한 변수
public String[] getReal_file_names() {
return real_file_names;
}
public void setReal_file_names(String[] real_file_names) {
this.real_file_names = real_file_names;
}
- boardMapper.xml에 insertAttach 쿼리를 추가한다.
<insert id="insertAttach">
insert into tbl_attach(save_file_name, real_file_name, bno)
values (#{save_file_name},#{real_file_name},(select bno from tbl_board order by bno desc limit 1))
</insert>
- select bno from tbl_board order by bno desc limit 1
- 업로드 할 때는 입력된 bno가 없기 때문에 bno=#{bno} 사용 불가능하다. 따라서 위의 쿼리를 사용하여 bno를 검색하여 입력한다.
- IF_BoardDAO.java 와 BoardDAOImpl
public void insertAttach(String save_file_name, String real_file_name) throws Exception;
- BoardDAOImpl에는 insertBoard 안에 추가한다.
@Transactional
@Override
public void insertBoard(BoardVO boardVO) throws Exception {
// 게시물 등록 DAO연결(아래)
boardDAO.insertBoard(boardVO);
// 첨부파일 등록 DAO연결(아래)
String[] save_file_names = boardVO.getSave_file_names();
String[] real_file_names = boardVO.getReal_file_names();
//첨부파일이 여러개일 때 상황 대비
if(save_file_names == null) {return;} //첨부파일 없을때
int index = 0;
String real_file_name="";
for(String save_file_name:save_file_names) {
real_file_name=real_file_names[index];
boardDAO.insertAttach(save_file_name, real_file_name);
index=index+1;
}
}
- AdminController.java의 oard_write에 업로드 관련 소스를 추가한다.
2. 파일 다운로드 구현 (CommonController.java)
- 파일 다운로드를 구현할 메소드를 생성한다.
@RequestMapping(value="/download", method=RequestMethod.GET)
@ResponseBody //이 어노테이션으로 지정된 메소드는 페이지 이동처리 아니고, RestAPI처럼 현재 페이지에서 구현 결과 내용을 전송 받음
public FileSystemResource download(
@RequestParam("save_file_name") String save_file_name,
@RequestParam("real_file_name") String real_file_name,
HttpServletResponse response
) throws Exception { //파일시스템리소스로 현재 페이지에서 반환받음.
File file = new File(uploadPath + "/"+ save_file_name); //다운받을 파일 경로 지정
response.setContentType("application/download; utf-8"); //파일"내용" 중 한글이 깨지는 것 방지
real_file_name = URLEncoder.encode(real_file_name, "UTF-8").replaceAll("\\+", "%20");
//위의 URLEncoder는 파일"명"이 한글(일본어, 베트남어)일 떄, 깨지는 것 방지.
response.setHeader("Content-Disposition", "attachment; filename="+real_file_name);
return new FileSystemResource(file); //실제 다운로드 시작
}
- File 클래스형 file 변수에 uploadPath에서 지정한 경로의 save_file_name을 저장한다.
'JAVA 기반 웹&앱 콘텐츠 융합 디지털 컨버전스 개발자 과정' 카테고리의 다른 글
[45일차] 스프링 시큐리티 (0) | 2021.01.13 |
---|---|
[42일차] 댓글 등록, 삭제, 수정 기능 구현 (0) | 2021.01.07 |
[31일차]- 삭제 & 삭제 메세지 JQuery 구현 (0) | 2020.12.27 |
[33일차] ERD 생성, AOP기능 (0) | 2020.12.23 |
[30일차]- 페이징처리 (0) | 2020.12.19 |