Spring

[Spring] 이미지 파일 업로드 & 변경

코딩 수달 2022. 9. 28. 11:49
반응형

이미지 업로드 

 

1. VIEW 

 

사진을 업로드할 insert.do에서는 하기와 같이 업로드 form을 생성할 때 이미지일 경우네는 enctype으로 인코딩 설정이 별도로 필요하다. 

<form action="insertBoard.do" method="post" enctype="multipart/form-data">
	<table>
		<thead>
			<tr>
				<td><input type="text" name="title"  placeholder="제목 작성란"></td>
				<td><input type="text" name="content"  placeholder="내용 작성란"></td>
				<td><input type="hidden" name="writer" value="${member.mid}"></td>
				<td><input type="file" name="uploadFile"/></td>
				<td><input type="submit" class="button" value="글 등록"></td>
			</tr>
		</thead>
	</table>
</form>

2. VO 추가 

 

멤버변수에 MultipartFile의 형식으로 사용자가 올린 사진을 원하는 경로에 저장이 가능하도록 생성해준다. (import 필요) 

String 타입으로 파일명을 저장할 용도로 만들 filename은 올린 이미지를 변경할 때 사용된다. 

package com.kim.biz.board;

import org.springframework.web.multipart.MultipartFile;

public class BoardVO {
	private int bid;
	private String title;
	private String writer;
	private String content;
	private int cnt;
	private String regdate;
	
	//검색 필터 
	private String searchCondition;
	private String searchContent;
	//이미지 업로드 
	private MultipartFile uploadFile;//사용자가 올린 사진을 원하는 경로에 저장 
	private String filename;//파일명을 저장할 칼럼 
	
	
	public String getFilename() {
		return filename;
	}
	public void setFilename(String filename) {
		this.filename = filename;
	}
	public String getSearchCondition() {
		return searchCondition;
	}
	public void setSearchCondition(String searchCondition) {
		this.searchCondition = searchCondition;
	}
	public String getSearchContent() {
		return searchContent;
	}
	public void setSearchContent(String searchContent) {
		this.searchContent = searchContent;
	}
	public MultipartFile getUploadFile() {
		return uploadFile;
	}
	public void setUploadFile(MultipartFile uploadFile) {
		this.uploadFile = uploadFile;
	}
	public int getBid() {
		return bid;
	}
	public void setBid(int bid) {
		this.bid = bid;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public int getCnt() {
		return cnt;
	}
	public void setCnt(int cnt) {
		this.cnt = cnt;
	}
	public String getRegdate() {
		return regdate;
	}
	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}
	@Override
	public String toString() {
		return "BoardVO [bid=" + bid + ", title=" + title + ", writer=" + writer + ", content=" + content + ", cnt="
				+ cnt + ", regdate=" + regdate + ", searchCondition=" + searchCondition + ", searchContent="
				+ searchContent + ", uploadFile=" + uploadFile + ", filename=" + filename + "]";
	}
}

3. 라이브러리 추가 

 

위에 사용한 MultipartFile을 사용하려면 FileUpdate 라이브러리(.jar) 추가해야한다. 

jar, 라이브러리를 추가하기 위해서는 pom.xml을 수정하면 된다.

 

하기 코드를 pom.xml 에 추가한다. 

<!-- FileUpload-->
      <dependency>
         <groupId>commons-fileupload</groupId>
         <artifactId>commons-fileupload</artifactId>
         <version>1.3.1</version>
      </dependency>

하기와 같이 Maven Dependencies에 라이브러리를 확인하였을 때 추가가 되어있으면 설정 완료! 


4. MultipartResolver 설정

 

Resolver설정은  dispatcherServlet-servlet.xml에서 해주기 때문에 MultipartFile사용하기 위한  MultipartResolver 설정도 이곳에 해준다. 

이때 id를 변경하면 사용이 불가하기 때문에 절대 변경하면 안된다! 

	<!-- 파일 업로드 관련 설정  -->
	 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="10000000" /> <!-- value=-1을 쓰면 무제한 -->
	</bean>

5. Controller 

 

View에서 데이터를 전송해주면 Controller에서는 Command 객체에 셋팅을 해주어야 하는데

이 과정에서 내부적으로 new  MultipartFile();을 해야한다. 

이때 new  MultipartFile();은 스프링 컨테이너가 관리한다. 

	@RequestMapping("/insertBoard.do")
	public String insertBoard(BoardVO bVO) throws IllegalStateException, IOException {
		
		//업로드 파일을 가져옴 
		MultipartFile uploadFile=bVO.getUploadFile();
		
		if(!uploadFile.isEmpty()) { //업로드한 파일 존재여부 확인
			//업로드한 파일명 
			String fileName=uploadFile.getOriginalFilename();
			//업로드한 파일을 지정한 경로에 저장
			uploadFile.transferTo(new File("C:\\0607KIM\\workspace2\\test0919\\src\\main\\webapp\\images\\"+fileName));
			
			bVO.setFilename(fileName);
		}

		boardService.insertBoard(bVO);
		return "redirect:main.do";
	}

업로드된 이미지 파일 변경 

1. TABLE 컬럼 추가 

 

업로드 이미지 파일을 변경하기 위해서는 VO에 String 타입의 사진을 저장할 변수가 필요하고 

DAO update의 sql문에도 변경할 파일을 추가해두어야 하기 때문에 컬럼을 추가한다. 

CREATE TABLE BOARD(
	BID INT PRIMARY KEY,
	TITLE VARCHAR(50) NOT NULL,
	WRITER VARCHAR(50) NOT NULL,
	CONTENT VARCHAR(100) NOT NULL,
	CNT INT DEFAULT 0,
	REGDATE DATE DEFAULT SYSDATE,
	FILENAME VARCHAR(1000) 
);

2. VO 추가 

 

String 타입으로 파일명을 저장할 용도로 filename 멤버변수를 추가한다.  

package com.kim.biz.board;

import org.springframework.web.multipart.MultipartFile;

public class BoardVO {
	private int bid;
	private String title;
	private String writer;
	private String content;
	private int cnt;
	private String regdate;
	
	//검색 필터 
	private String searchCondition;
	private String searchContent;
	//이미지 업로드 
	private MultipartFile uploadFile;//사용자가 올린 사진을 원하는 경로에 저장 
	private String filename;//파일명을 저장할 칼럼 
	
	
	public String getFilename() {
		return filename;
	}
	public void setFilename(String filename) {
		this.filename = filename;
	}
	public String getSearchCondition() {
		return searchCondition;
	}
	public void setSearchCondition(String searchCondition) {
		this.searchCondition = searchCondition;
	}
	public String getSearchContent() {
		return searchContent;
	}
	public void setSearchContent(String searchContent) {
		this.searchContent = searchContent;
	}
	public MultipartFile getUploadFile() {
		return uploadFile;
	}
	public void setUploadFile(MultipartFile uploadFile) {
		this.uploadFile = uploadFile;
	}
	public int getBid() {
		return bid;
	}
	public void setBid(int bid) {
		this.bid = bid;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public int getCnt() {
		return cnt;
	}
	public void setCnt(int cnt) {
		this.cnt = cnt;
	}
	public String getRegdate() {
		return regdate;
	}
	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}
	@Override
	public String toString() {
		return "BoardVO [bid=" + bid + ", title=" + title + ", writer=" + writer + ", content=" + content + ", cnt="
				+ cnt + ", regdate=" + regdate + ", searchCondition=" + searchCondition + ", searchContent="
				+ searchContent + ", uploadFile=" + uploadFile + ", filename=" + filename + "]";
	}
}

3. DAO 수정 

 

Table에 추가한 filename 컬럼이 insert, update 에 추가되어야하기 때문에 수정해준다. 

package com.kim.biz.board.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.kim.biz.board.BoardVO;

@Repository("boardDAO")
public class BoardDAO2 {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	final String sql_selectOne="SELECT * FROM BOARD WHERE BID=?";
	final String sql_selectAll="SELECT * FROM BOARD ORDER BY BID DESC";
	final String sql_insert="INSERT INTO BOARD(BID,TITLE,WRITER,CONTENT,FILENAME) VALUES((SELECT NVL(MAX(BID),0)+1 FROM BOARD),?,?,?,?)";
	final String sql_update="UPDATE BOARD SET TITLE=?,CONTENT=?,FILENAME=? WHERE BID=?";
	final String sql_delete="DELETE BOARD WHERE BID=?";
	final String sql_selectAll_T="SELECT * FROM BOARD WHERE TITLE LIKE '%'||?||'%' ORDER BY BID DESC";
	final String sql_selectAll_w="SELECT * FROM BOARD WHERE WRITER LIKE '%'||?||'%' ORDER BY BID DESC";

	void insertBoard(BoardVO vo) {
		jdbcTemplate.update(sql_insert,vo.getTitle(),vo.getWriter(),vo.getContent(),vo.getFilename());
	}
	void updateBoard(BoardVO vo) {
		jdbcTemplate.update(sql_update,vo.getTitle(),vo.getContent(),vo.getFilename(),vo.getBid());
	}
	void deleteBoard(BoardVO vo) {
		jdbcTemplate.update(sql_delete,vo.getBid());
	}
	BoardVO selectOneBoard(BoardVO vo) {
		Object[] args= {vo.getBid()};
		return jdbcTemplate.queryForObject(sql_selectOne,args,new BoardRowMapper());
	}
	List<BoardVO> selectAllBoard(BoardVO vo) {
		if(vo.getTitle()!=null) {
			Object[] args= {vo.getTitle()};
			return jdbcTemplate.query(sql_selectAll_T,args,new BoardRowMapper());
		}else if(vo.getWriter()!=null) {
			Object[] args= {vo.getWriter()};
			return jdbcTemplate.query(sql_selectAll_w,args,new BoardRowMapper());
		}
		return jdbcTemplate.query(sql_selectAll,new BoardRowMapper());
	}
}

class BoardRowMapper implements RowMapper<BoardVO>{

	@Override
	public BoardVO mapRow(ResultSet rs, int rowNum) throws SQLException {
		BoardVO data=new BoardVO();
		data.setBid(rs.getInt("BID"));
		data.setContent(rs.getString("CONTENT"));
		data.setTitle(rs.getString("TITLE"));
		data.setWriter(rs.getString("WRITER"));
		data.setCnt(rs.getInt("CNT"));
		data.setRegdate(rs.getString("REGDATE"));
		data.setFilename(rs.getString("FILENAME"));
		return data;
	}
}

4.VIEW 

							<form action="updateBoard.do" method="POST" enctype="multipart/form-data">
								<input type="hidden" name="bid" value="${data.bid}">
								<table>
									<thead>
										<tr>
											<th>title</th>
											<th>content</th>
											<th>writer</th>
											<th>imageupload</th>
											<th>image</th>
											<th>regdate</th>
									</thead>
									<tbody>

								<tr>
									<td><input type="text" name="title" value="${data.title}"></td>
									<td><input type="text" name="content" value="${data.content}"></td>
									<td>"${data.writer}"</td>
									<td><input type="file" name="uploadFile" value="${data.filename}"></td>
									<td><img src="images/${data.filename}" id="imgSize"/></td>
									<td><input type="datetime-local" name="regdate"value="${data.regdate}"></td>
								</tr>
반응형