[게시판 만들기]9.파일(이미지) 업로드(+글작성)

JINI·2022년 12월 2일
0
post-thumbnail

🧩이미지 추가하기

그전에는 이미지없이 게시글을 작성했다면 이번에는 원하는 이미지를 선택해 글을 작성한다.


💡이미지를 업로드 하기 위해선 파일 관련 의존성 처리를 해야한다.

  • pom.xml에 코드를 추가한다.
<!-- commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

<!-- commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>!

🔧빈(bean) 만들기

<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<beans:property name="maxUploadSize" value="52428800" />
	<beans:property name="defaultEncoding" value="utf-8" />
</beans:bean>

🎨jsp

  • 이미지 추가를 위해 글쓰기 페이지에 코드를 추가한다.
<script type="text/javascript">

   function readURL(input) {
      var file = input.files[0] 
      console.log(file)
      if (file != '') {
         var reader = new FileReader();
         reader.readAsDataURL(file);
         reader.onload = function (e) { 
	     console.log(e.target)
		console.log(e.target.result)
           $('#preview').attr('src', e.target.result);
          }
      }
  }  
</script>
  • var file = input.files[0] 은 파일에 대한 정보
  • reader.readAsDataURL(file); 로 파일의 정보를 토대로 파일을 읽고
  • reader.onload = function (e)은 파일 로드한 값을 표현하는데
    여기서 e는 이벤트 안에 result 값이 파일의 정보(위치)를 가지고 있다.

<form method="post" action="${contextPath}/board/writeSave" enctype="multipart/form-data">
	<div class="form-group" style="height: 150px; width: 200px;">
			<label>이미지 파일 첨부</label> 
            <input type="file" name="imgFile" onchange="readURL(this);"/>
			<img id="preview" src="#" width=200 height=150 alt="선택된 이미지가 없습니다" style="align-content: flex-end; ">
	</div>
</form>
  • 파일을 보내기 위해enctype="multipart/form-data"form에 추가한다.

📕fileService/fileServiceImpl

  • 이미지 관련 코드는 분리해 만들려고 새로운 파일을 만들었다.
public static final String IMAGE_REPO="C:/spring/image_repo";
public String saveFile(MultipartFile file);
  • 글 작성시 이미지를 추가할 때 해당 이미지를 저장할 경로를 만들어준다.
  • 저장이미지 메소드를 만들어준다.
public String saveFile(MultipartFile file) {
		SimpleDateFormat simpl = new SimpleDateFormat("yyyyMMddHHmmss-");
		Calendar calendar = Calendar.getInstance();
		String sysFileName = 
			simpl.format(calendar.getTime()) + file.getOriginalFilename();
		File saveFile = new File(IMAGE_REPO+"/"+sysFileName);
		try {
			file.transferTo(saveFile);//해당 위치에 파일 저장
		}catch (Exception e) {
			e.printStackTrace();
		}
		return sysFileName;
	}
  • 이미지 파일 이름은 작성 날짜 형태로 저장되도록 한다.
  • try/catch로 성공시 해당 위치에 파일 저장하고 파일 이름을 돌려주며 실패하면 서버에서만 오류 메시지를 띄우도록 한다.

📕serviceImpl

  • 이미지 올리기 코드는 글 저장하는 코드에 추가한다.
public String writeSave(MultipartHttpServletRequest multi, HttpServletRequest request) {
		
        사용자가 넘긴 multi,request를 dto에 저장하는 코드는 생략
		
		MultipartFile file = multi.getFile("imgFile");
		boardFileService bfs = new boardFileServiceImpl();   
		if(file.getSize() != 0) {
			dto.setImgFile(bfs.saveFile(file));
		}
		else{
			dto.setImgFile("nan"); 
		}
		int result = 0;
		try {
			result = mapper.writeSave(dto);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bfs.getMessage(result, request); //저장된 dto를 mapper로 전달
	}
  • 사용자 정보를 저장하는 multi에 이미지 파일을 가져오고 boardFileService 객체를 만들어서 가져온다. 이 코드는 @service 어노테이션을 넣고 Autowired로 주입하면 쓰지 않아도 된다.
  • 파일을 선택했다면 dto에 이미지를 저장하고 service로 보내고 선택한 파일이 없다면 nan값으로 dto에 저장한다.
  • 돌려받을 값을 result로 만들고 try/catch
    로 사용자에게 보이면 안되는 오류 메시지는 전부 예외처리한다.
    성공시 mapper로 보낼 값을 result에 넣고 저장된 dto를 mapper로 전달한다.

📕mapper.xml

	<insert id="writeSave">
		insert into
		talk_board(write_num,title,writer,content, img_file)
		values(talk_board_seq.nextval,#{title},#{writer},
		#{content},#{imgFile} )
	</insert>
  • 글 작성 후 저장하는 쿼리문에 이미지도 추가(img_file, #{imgFile})한다.

📕Controller

  • 이미지를 불러오는 코드를 작성한다
@GetMapping("imageView")
	public void imgView(@RequestParam("imgFile") String imgFile,
		HttpServletResponse response) throws IOException {
	    response.addHeader(
		"Content-disposition","attachment;fileName="+imgFile); //파일을 다운받고, 브라우저로 표현하고, 다운될 파일이름
	    File file = new File(boardFileService.IMAGE_REPO+"/"+imgFile);
	    FileInputStream in = new FileInputStream(file);
	    FileCopyUtils.copy(in, response.getOutputStream());
	    in.close();
  • @RequestParam으로 dto를 가져오고 이미지 요청에 대한 응답으로 파일을 다운받고 FileInputStream 으로 객체를 생성할 때 데이터를 읽어올 방법을 지정했다.
  • FileCopyUtils.copy로 파일을 inputStream으로 받는다.

profile
꾸준히 성장하는 개발자

1개의 댓글

comment-user-thumbnail
2023년 8월 11일

빈bean은 어느파일에 추가하는 건가요?

답글 달기