Project/Final (20.10.05-20.11.17)

2020.11.13.(금) (프로필 사진) 파일 업로드 - 서버에 파일 저장, 프로필 변경하면 img 태그에 반영되도록 하기

myspace 2020. 11. 15. 15:13

(마이페이지 프로필 사진) 파일 업로드

1. pom.xml

		<!-- common fileupload -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.8.0</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.4</version>
		</dependency>

2. FileUploadUtils.java

package com.minibean.timewizard.utils.file;

import java.util.Date;
import java.util.UUID;

import org.springframework.stereotype.Component;

@Component
public class FileUploadUtils {
	
	public String makeRandomName() {
		Date date = new Date();
		UUID uuid = UUID.randomUUID();
		return uuid.toString() + "-" + date.getTime();
	}

}

3. FileValidator.java

package com.minibean.timewizard.utils.file;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.minibean.timewizard.model.dto.FileUploadDto;

@Component
public class FileValidator implements Validator {

	@Override
	public boolean supports(Class<?> clazz) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void validate(Object target, Errors errors) {
		// 주어진 객체 target의 유효성 검사
		// target - supports(Class<?> clazz)가 일반적으로 true를 반환하는 클래스
		// Errors : 데이터 바인딩 및 유효성 검사 오류에 대한 정보 저장 및 노출(store and expose)
		FileUploadDto file = (FileUploadDto) target;
		
		if (file.getFile().getSize() == 0) {
			errors.rejectValue("file", "fileNPE", "Please select a file");
		}
		// regectValue(String field, String errorCode, String defaultMessage)
		// 지정된 필드에 대한 필드 오류 및 설명 등록

	}

}

4. src/main/resources/mybatis/file_upload-mapper.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.minibean.timewizard.fileupload">
	<select id="selectVideoList" parameterType="int" resultType="FileUploadDto">
		SELECT FILE_NO, USER_NO, FILE_NAME, FILE_TYPE, FILE_REGDATE
		FROM FILE_UPLOAD
		WHERE USER_NO = #{user_no}
		AND FILE_TYPE = 'V'
		AND FILE_REGDATE >= TO_DATE(TO_CHAR((SYSDATE-6),'YYYYMMDD'),'YYYYMMDD')
		ORDER BY FILE_NO DESC
		<!-- SYSDATE - 6? SYSDATE - 7? -->
	</select>
	<select id="selectImageOne" parameterType="int" resultType="FileUploadDto">
		SELECT FILE_NO, USER_NO, FILE_NAME, FILE_TYPE, FILE_REGDATE
		FROM (SELECT FILE_NO, USER_NO, FILE_NAME, FILE_TYPE, FILE_REGDATE
			FROM FILE_UPLOAD
			WHERE USER_NO = #{user_no}
			AND FILE_TYPE = 'I'
			ORDER BY FILE_NO DESC)
		WHERE ROWNUM = 1
	</select>
	<select id="selectVideoOne" parameterType="int" resultType="FileUploadDto">
		SELECT FILE_NO, USER_NO, FILE_NAME, FILE_TYPE, FILE_REGDATE
		FROM FILE_UPLOAD
		WHERE FILE_NO = #{file_no}
		AND FILE_TYPE = 'V'
	</select>
	<select id="selectOne" parameterType="int" resultType="FileUploadDto">

		SELECT FILE_NO, USER_NO, FILE_NAME, FILE_TYPE, FILE_REGDATE
		FROM FILE_UPLOAD
		WHERE FILE_NO = #{file_no}
	</select>
	
	<insert id="insert" parameterType="FileUploadDto">
		INSERT INTO FILE_UPLOAD
		VALUES(FILE_UPLOAD_SEQ.NEXTVAL, #{user_no}, #{file_name}, #{file_type}, SYSDATE)
	</insert>
</mapper>

5. FileUploadDao.java

package com.minibean.timewizard.model.dao;

import java.util.List;

import com.minibean.timewizard.model.dto.FileUploadDto;

public interface FileUploadDao {

	String NAMESPACE="com.minibean.timewizard.fileupload.";
	
	public List<FileUploadDto> selectVideoList(int user_no);
	public FileUploadDto selectImageOne(int user_no);
	public FileUploadDto selectVideoOne(int file_no);
	public FileUploadDto selectOne(int file_no);
	public int insert(FileUploadDto dto);
	
}

6. FileUploadDaoImpl.java

package com.minibean.timewizard.model.dao;

import java.util.ArrayList;
import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.minibean.timewizard.model.dto.FileUploadDto;

@Repository
public class FileUploadDaoImpl implements FileUploadDao {
	
	@Autowired
	private SqlSessionTemplate sqlSession;
	private Logger logger = LoggerFactory.getLogger(FileUploadDaoImpl.class);

	@Override
	public List<FileUploadDto> selectVideoList(int user_no) {
		logger.info(">> [FILEUPLOAD] selectVideoList - " + user_no);
		List<FileUploadDto> list = new ArrayList<FileUploadDto>();
		try {
			list = sqlSession.selectList(NAMESPACE+"selectVideoList", user_no);
		} catch (Exception e) {
			logger.info("[ERROR] FILEUPLOAD :: selectList");
			e.printStackTrace();
		}
		return list;
	}

	@Override
	public FileUploadDto selectImageOne(int user_no) {
		logger.info(">> [FILEUPLOAD] selectImageOne - " + user_no);
		FileUploadDto dto = null;
		try {
			dto = sqlSession.selectOne(NAMESPACE+"selectImageOne", user_no);
		} catch (Exception e) {
			logger.info("[ERROR] FILEUPLOAD :: selectOne");
			e.printStackTrace();
		}
		return dto;
	}
	
	@Override
	public FileUploadDto selectOne(int file_no) {
		logger.info(">> [FILEUPLOAD] selectOne - " + file_no);
		FileUploadDto dto = null;
		try {
			dto = sqlSession.selectOne(NAMESPACE+"selectOne", file_no);
		} catch (Exception e) {
			logger.info("[ERROR] FILEUPLOAD :: selectOne");
			e.printStackTrace();
		}
		return dto;
	}
	
	@Override
	public FileUploadDto selectVideoOne(int file_no) {
		logger.info(">> [FILEUPLOAD] selectOne - " + file_no);
		FileUploadDto dto = null;
		try {
			dto = sqlSession.selectOne(NAMESPACE+"selectVideoOne", file_no);
		} catch (Exception e) {
			logger.info("[ERROR] FILEUPLOAD :: selectOne");
			e.printStackTrace();
		}
		return dto;
	}

	@Override
	public int insert(FileUploadDto dto) {
		logger.info(">> [FILEUPLOAD] insert");
		int res = 0;
		try {
			res = sqlSession.insert(NAMESPACE+"insert", dto);
		} catch (Exception e) {
			logger.info("[ERROR] FILEUPLOAD :: insert");
			e.printStackTrace();
		}
		return res;
	}

}

7. FileUploadBiz.java

package com.minibean.timewizard.model.biz;

import java.util.List;

import com.minibean.timewizard.model.dto.FileUploadDto;

public interface FileUploadBiz {
	
	public List<FileUploadDto> selectVideoList(int user_no);
	public FileUploadDto selectImageOne(int user_no);
	public FileUploadDto selectVideoOne(int file_no);
	public FileUploadDto selectOne(int file_no);
	public int insert(FileUploadDto dto);
	
}

8. FileUploadBizImpl.java

package com.minibean.timewizard.model.biz;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.minibean.timewizard.model.dao.FileUploadDao;
import com.minibean.timewizard.model.dto.FileUploadDto;

@Service
public class FileUploadBizImpl implements FileUploadBiz {

	@Autowired
	private FileUploadDao fileUploadDao;
	
	@Override
	public List<FileUploadDto> selectVideoList(int user_no) {
		return fileUploadDao.selectVideoList(user_no);
	}

	@Override
	public FileUploadDto selectImageOne(int user_no) {
		return fileUploadDao.selectImageOne(user_no);
	}
	
	@Override
	public FileUploadDto selectVideoOne(int file_no) {
		return fileUploadDao.selectVideoOne(file_no);
	}
	
	@Override
	public FileUploadDto selectOne(int file_no) {
		return fileUploadDao.selectOne(file_no);
	}

	@Override
	public int insert(FileUploadDto dto) {
		return fileUploadDao.insert(dto);
	}

}

9. FileUploadDto.java

package com.minibean.timewizard.model.dto;

import java.util.Date;

import org.springframework.web.multipart.MultipartFile;

public class FileUploadDto {

	private int file_no;
	private int user_no;
	private String file_name;
	private String file_type;
	private int file_size;
	private Date file_regdate;
	private MultipartFile file;
	
	public FileUploadDto() {}
	public FileUploadDto(MultipartFile file) {
		this.file = file;
	}
	public FileUploadDto(int file_no, int user_no, String file_name, String file_type, int file_size,
			Date file_regdate) {
		this.file_no = file_no;
		this.user_no = user_no;
		this.file_name = file_name;
		this.file_type = file_type;
		this.file_size = file_size;
		this.file_regdate = file_regdate;
	}
	public FileUploadDto(int file_no, int user_no, String file_name, String file_type, int file_size, Date file_regdate,
			MultipartFile file) {
		this.file_no = file_no;
		this.user_no = user_no;
		this.file_name = file_name;
		this.file_type = file_type;
		this.file_size = file_size;
		this.file_regdate = file_regdate;
		this.file = file;
	}
	public int getFile_no() {
		return file_no;
	}
	public void setFile_no(int file_no) {
		this.file_no = file_no;
	}
	public int getUser_no() {
		return user_no;
	}
	public void setUser_no(int user_no) {
		this.user_no = user_no;
	}
	public String getFile_name() {
		return file_name;
	}
	public void setFile_name(String file_name) {
		this.file_name = file_name;
	}
	public String getFile_type() {
		return file_type;
	}
	public void setFile_type(String file_type) {
		this.file_type = file_type;
	}
	public int getFile_size() {
		return file_size;
	}
	public void setFile_size(int file_size) {
		this.file_size = file_size;
	}
	public Date getFile_regdate() {
		return file_regdate;
	}
	public void setFile_regdate(Date file_regdate) {
		this.file_regdate = file_regdate;
	}
	public MultipartFile getFile() {
		return file;
	}
	public void setFile(MultipartFile file) {
		this.file = file;
	}
	
}

10. user_info-mapper.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.minibean.timewizard.userinfo">

	<select id="selectList" resultType="UserInfoDto">
		SELECT USER_NO, USER_ID, USER_PW, USER_NAME, USER_EMAIL, 
		USER_ROLE, USER_PHOTO, USER_ACTIVE, USER_DISTINCT, USER_REGDATE
		FROM USER_INFO
		ORDER BY USER_NO
	</select>
	
	<select id="selectOneUserNo" parameterType="int" resultType="UserInfoDto">
		SELECT USER_NO, USER_ID, USER_PW, USER_NAME, USER_EMAIL, 
		USER_ROLE, USER_PHOTO, USER_ACTIVE, USER_DISTINCT, USER_REGDATE
		FROM USER_INFO
		WHERE USER_NO = #{user_no}
	</select>
	
	<select id="selectOneUserInfoDto" parameterType="UserInfoDto" resultType="UserInfoDto">
		SELECT ui.USER_NO, ui.USER_ID, ui.USER_PW, ui.USER_NAME, ui.USER_EMAIL, 
			ui.USER_ROLE, ui.USER_PHOTO, ui.USER_ACTIVE, ui.USER_DISTINCT, ui.USER_REGDATE 
		FROM USER_INFO ui 
		WHERE USER_ID = #{user_id}
		AND USER_PW = #{user_pw}
		AND USER_ACTIVE = 'Y'
	</select>
	
	<select id="selectOneUserDistinct" parameterType="String" resultType="UserInfoDto">
		SELECT USER_NO, USER_ID, USER_PW, USER_NAME, USER_EMAIL, 
		USER_ROLE, USER_PHOTO, USER_ACTIVE, USER_DISTINCT, USER_REGDATE
		FROM USER_INFO
		WHERE USER_DISTINCT = #{user_distinct}
		AND USER_ACTIVE = 'Y'
	</select>
	
	<insert id="insert" parameterType="UserInfoDto">
		INSERT INTO USER_INFO
		VALUES(USER_INFO_SEQ.NEXTVAL, #{user_id}, #{user_pw}, #{user_name},
		#{user_email}, 'USER', NULL, 'Y', #{user_distinct}, SYSDATE)
	</insert>
	
	<update id="update" parameterType="UserInfoDto">
		UPDATE USER_INFO SET USER_NAME = #{user_name},
		USER_EMAIL = #{user_email}, USER_DISTINCT = #{user_distinct}
		WHERE USER_NO = #{user_no}
	</update>
	
	<update id="delete" parameterType="int">
		UPDATE USER_INFO SET USER_ACTIVE = 'N'
		WHERE USER_NO = #{user_no}
	</update>
	
	<select id="idCheck" parameterType="UserInfoDto" resultType="int">
		SELECT COUNT(user_id)
		FROM USER_INFO
		WHERE USER_ID = #{user_id}
	</select>

	<update id="updateRoleRes" parameterType="UserInfoDto">
		UPDATE USER_INFO
		SET
		<if test="user_role != null and user_role != ''">
		USER_ROLE = #{user_role}
		</if>
		WHERE user_no = #{user_no}
	</update>
	
	<update id="pwChangeRes" parameterType="UserInfoDto">
		UPDATE USER_INFO SET USER_PW = #{user_newestpw}
		WHERE USER_NO = #{user_no}
	</update>
	
	<update id="userInfoChange" parameterType="UserInfoDto">
		UPDATE USER_INFO SET USER_NAME = #{user_name},
		USER_EMAIL = #{user_email}
		WHERE USER_NO = #{user_no}
	</update>
	
	<update id="profileChange" parameterType="UserInfoDto">
		UPDATE USER_INFO SET USER_PHOTO = #{user_photo}
		WHERE USER_NO = #{user_no}
	</update>

	<!-- id찾기 -->
	<select id="findID" parameterType="String" resultType="UserInfoDto">
		SELECT *
		FROM USER_INFO
		WHERE USER_EMAIL = #{user_email}
	</select>
	
	<!-- password찾기 -->
	<select id="findPW" parameterType="hashmap" resultType="UserInfoDto">
		SELECT *
		FROM USER_INFO
		WHERE USER_ID = #{user_id}
		AND USER_EMAIL = #{user_email}
	</select>
	
</mapper>

11. UserInfoDao.java

package com.minibean.timewizard.model.dao;

import java.util.HashMap;
import java.util.List;

import com.minibean.timewizard.model.dto.UserInfoDto;

public interface UserInfoDao {

	String NAMESPACE = "com.minibean.timewizard.userinfo.";
	
	public List<UserInfoDto> selectList();
	public UserInfoDto selectOne(int user_no); /* session용 */
	public UserInfoDto selectOne(String user_distinct); /* personal용 */
	public UserInfoDto selectOne(UserInfoDto dto); /* 기타용 */
	public int insert(UserInfoDto dto);
	public int update(UserInfoDto dto);
	public int delete(int user_no);
	public int idCheck(String id);
	public int updateRoleRes(UserInfoDto dto);
	public int pwChangeRes(UserInfoDto dto);
	public int userInfoChange(UserInfoDto dto);
	public int profileChange(UserInfoDto dto);
	
	//아이디 찾기
	public UserInfoDto findID(String user_email);
	//비밀번호 찾기
	public UserInfoDto findPW(HashMap<String, Object> map);
	
}

12. UserInfoDaoImpl.java

package com.minibean.timewizard.model.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.minibean.timewizard.model.dto.UserInfoDto;

@Repository
public class UserInfoDaoImpl implements UserInfoDao {
	
	@Autowired
	private SqlSessionTemplate sqlSession;
	private static final Logger logger = LoggerFactory.getLogger(UserInfoDaoImpl.class);
	
	@Override
	public List<UserInfoDto> selectList() {
		logger.info(">> [USERINFO] selectList");
		
		List<UserInfoDto> result = new ArrayList<UserInfoDto>();
		try {
			result = sqlSession.selectList(NAMESPACE+"selectList");
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: selectList");
			e.printStackTrace();
		}
		
		return result;
	}

	@Override
	public UserInfoDto selectOne(int user_no) {
		logger.info(">> [USERINFO] selectOne by user_no - " + user_no);
		UserInfoDto result = null;
		
		try {
			result = sqlSession.selectOne(NAMESPACE+"selectOneUserNo", user_no);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: selectOne by user_no");
			e.printStackTrace();
		}
		
		return result;
	}
	@Override
	public UserInfoDto selectOne(String user_distinct) {
		logger.info(">> [USERINFO] selectOne by user_distinct");
		UserInfoDto result = null;
		
		try {
			result = sqlSession.selectOne(NAMESPACE+"selectOneUserDistinct", user_distinct);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: selectOne by user_distinct");
			e.printStackTrace();
		}
		return result;
	}

	@Override
	public UserInfoDto selectOne(UserInfoDto dto) {
		UserInfoDto result = null;
		
		try {
			result = sqlSession.selectOne(NAMESPACE+"selectOneUserInfoDto", dto);
			logger.info(">> [USERINFO] selectOne by UserInfoDto - " + dto.getUser_no());
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: selectOne by UserInfoDto");
			e.printStackTrace();
		}
		
		return result;
	}

	@Override
	public int insert(UserInfoDto dto) {
		logger.info(">> [USERINFO] insert");
		int res = 0;
		
		try {
			res = sqlSession.insert(NAMESPACE+"insert", dto);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: insert");
			e.printStackTrace();
		}
		
		return res;
	}

	@Override
	public int update(UserInfoDto dto) {
		logger.info(">> [USERINFO] update : user_no - " + dto.getUser_no());
		int res = 0;
		
		try {
			res = sqlSession.update(NAMESPACE+"update", dto);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: update");
			e.printStackTrace();
		}
		
		return res;
	}

	@Override
	public int delete(int user_no) {
		logger.info(">> [USERINFO] user unscribe");
		int res = 0;
		
		try {
			res = sqlSession.update(NAMESPACE+"delete", user_no);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: unscribe");
			e.printStackTrace();
		}
		
		return res;
	}
	
	@Override
	public int idCheck(String id) {
		int cnt=sqlSession.selectOne(NAMESPACE+"idCheck", id);
		return cnt;
	}
	
	@Override
	public int updateRoleRes(UserInfoDto dto) {
		logger.info(">> [USERINFO] update : user_role - " + dto.getUser_role());
		int res = 0;
		
		try {
			res = sqlSession.update(NAMESPACE+"updateRoleRes", dto);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: updateRoleRes");
			e.printStackTrace();
		}
		
		return res;
	}
	
	@Override
	public int pwChangeRes(UserInfoDto dto) {
		logger.info(">> [USERINFO] update : user_pw - " + dto.getUser_newestpw());
		int res = 0;
		
		try {
			res = sqlSession.update(NAMESPACE+"pwChangeRes", dto);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: pwChangeRes");
			e.printStackTrace();
		}
		
		return res;
	}
	
	@Override
	public int userInfoChange(UserInfoDto dto) {
		logger.info(">> [USERINFO] update : user_name & user_email - " + dto.getUser_name() + " & " + dto.getUser_email());
		int res = 0;
		
		try {
			res = sqlSession.update(NAMESPACE+"userInfoChange", dto);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: userInfoChange");
			e.printStackTrace();
		}
		
		return res;
	}
	
	@Override
	public int profileChange(UserInfoDto dto) {
		logger.info(">> [USERINFO] update : user_photo - " + dto.getUser_photo());
		int res = 0;
		
		try {
			res = sqlSession.update(NAMESPACE+"profileChange", dto);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: profileChange");
			e.printStackTrace();
		}
		
		return res;
	}

	//아이디 찾기
	//이름, 이메일
	@Override
	public UserInfoDto findID(String user_email) {
		logger.info(">> [USERINFO] findID - user_email : "+user_email);
		UserInfoDto result = null;
		try {
			result = sqlSession.selectOne(NAMESPACE+"findID", user_email);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: findID");
			e.printStackTrace();
		}
		return result;
	}

	//비밀번호 찾기
	//이름,이메일,아이디
	@Override
	public UserInfoDto findPW(HashMap<String, Object> map) {
		logger.info(">> [USERINFO] findID : user_email & user_id  ");
		UserInfoDto result = null;
		try {
			result = sqlSession.selectOne(NAMESPACE+"findPW", map);
		} catch (Exception e) {
			logger.info("[ERROR] USERINFO :: findPW");
			e.printStackTrace();
		}
		return result;
	}

}

13. UserInfoBiz.java

package com.minibean.timewizard.model.biz;

import java.util.HashMap;
import java.util.List;

import com.minibean.timewizard.model.dto.UserInfoDto;

public interface UserInfoBiz {
	
	public List<UserInfoDto> selectList();
	public UserInfoDto selectOne(int user_no); /* session용 */
	public UserInfoDto selectOne(UserInfoDto dto); /* 기타용 */
	public UserInfoDto selectOne(String user_distinct); /* personal용 */
	public int insert(UserInfoDto dto);
	public int update(UserInfoDto dto);
	public int delete(int user_no);
	public int idCheck(String id);//아이디 중복체크 용도
	public int updateRoleRes(UserInfoDto dto);
	public int pwChangeRes(UserInfoDto dto);
	public int userInfoChange(UserInfoDto dto);
	public int profileChange(UserInfoDto dto);
	
	//아이디 찾기
	//이름,이메일
	public UserInfoDto findID(String user_email);
	//비밀번호 찾기
	//이름,이메일,아이디
	public UserInfoDto findPW(HashMap<String, Object> map);
}

14. UserInfoBizImpl.java

package com.minibean.timewizard.model.biz;

import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.minibean.timewizard.model.dao.UserInfoDao;
import com.minibean.timewizard.model.dto.UserInfoDto;
import com.minibean.timewizard.utils.login.UserInfoUtils;

@Service
public class UserInfoBizImpl implements UserInfoBiz {

	@Autowired
	private UserInfoDao userInfoDao;
	@Autowired
	private UserInfoUtils userInfoUtils;
	
	@Override
	public List<UserInfoDto> selectList() {
		return userInfoDao.selectList();
	}

	@Override
	public UserInfoDto selectOne(int user_no) {
		return userInfoDao.selectOne(user_no);
	}

	@Override
	public UserInfoDto selectOne(UserInfoDto dto) {
		return userInfoDao.selectOne(dto);
	}
	
	@Override
	public UserInfoDto selectOne(String user_distinct) {
		return userInfoDao.selectOne(user_distinct);
	}

	@Override
	public int insert(UserInfoDto dto) {
		try {
			dto.setUser_distinct(userInfoUtils.makeDistinctString(dto.getUser_id(), dto.getUser_email()));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			dto.setUser_distinct(dto.getUser_id());
		}
		return userInfoDao.insert(dto);
	}

	@Override
	public int update(UserInfoDto dto) {
		return userInfoDao.update(dto);
	}

	@Override
	public int delete(int user_no) {
		return userInfoDao.delete(user_no);
	}
	
	@Override
	public int idCheck(String id) {
		
		int cnt= userInfoDao.idCheck(id);
		return cnt;
	}
	
	@Override
	public int updateRoleRes(UserInfoDto dto) {
		return userInfoDao.updateRoleRes(dto);
	}
	
	@Override
	public int pwChangeRes(UserInfoDto dto) {
		return userInfoDao.pwChangeRes(dto);
	}
	
	@Override
	public int userInfoChange(UserInfoDto dto) {
		return userInfoDao.userInfoChange(dto);
	}
	
	@Override
	public int profileChange(UserInfoDto dto) {
		return userInfoDao.profileChange(dto);
	}

	//아이디 찾기
	@Override
	public UserInfoDto findID(String user_email) {
		return userInfoDao.findID(user_email);
	}

	//비밀번호 찾기
	@Override
	public UserInfoDto findPW(HashMap<String, Object> map) {
		return userInfoDao.findPW(map);
	}

}

15. UserInfoDto.java

package com.minibean.timewizard.model.dto;

import java.util.Date;

public class UserInfoDto {

	private int user_no;
	private String user_id;
	private String user_pw;
	private String user_newestpw;
	private String user_newestpw_check;
	private String user_name;
	private String user_email;
	private String user_role;
	private String user_photo;
	private String user_active;
	private String user_distinct;
	private Date user_regdate;
	private FriendDto friendDto;
	
	public UserInfoDto() {}


	public UserInfoDto(int user_no, String user_id, String user_pw, String user_name, String user_email,
			String user_role, String user_photo, String user_active, String user_distinct, Date user_regdate) {
		super();
		this.user_no = user_no;
		this.user_id = user_id;
		this.user_pw = user_pw;
		this.user_name = user_name;
		this.user_email = user_email;
		this.user_role = user_role;
		this.user_photo = user_photo;
		this.user_active = user_active;
		this.user_distinct = user_distinct;
		this.user_regdate = user_regdate;
	}
	
	// 회원정보조회
	public UserInfoDto(int user_no, String user_id, String user_pw, String user_name, String user_email,
			String user_active, Date user_regdate, String user_role) {
		super();
		this.user_no = user_no;
		this.user_id = user_id;
		this.user_pw = user_pw;
		this.user_name = user_name;
		this.user_email = user_email;
		this.user_active = user_active;
		this.user_regdate = user_regdate;
		this.user_role = user_role;
	}
	
	// update
	public UserInfoDto(int user_no, String user_pw, String user_name, String user_email, String user_distinct) {
		this.user_no = user_no;
		this.user_pw = user_pw;
		this.user_name = user_name;
		this.user_email = user_email;
		this.user_distinct = user_distinct;
	}
	
	// updateRoleRes
	public UserInfoDto(int user_no, String user_role) {
		this.user_no = user_no;
		this.user_role = user_role;
	}
	
	// user_newpw, user_newestpw_check 추가
	public UserInfoDto(int user_no, String user_id, String user_pw, String user_newestpw, String user_newestpw_check, String user_name,
			String user_email, String user_role, String user_photo, String user_active, String user_distinct,
			Date user_regdate, FriendDto friendDto) {
		this.user_no = user_no;
		this.user_id = user_id;
		this.user_pw = user_pw;
		this.user_newestpw = user_newestpw;
		this.user_newestpw_check = user_newestpw_check;
		this.user_name = user_name;
		this.user_email = user_email;
		this.user_role = user_role;
		this.user_photo = user_photo;
		this.user_active = user_active;
		this.user_distinct = user_distinct;
		this.user_regdate = user_regdate;
		this.friendDto = friendDto;
	}
	
	public int getUser_no() {
		return user_no;
	}

	public void setUser_no(int user_no) {
		this.user_no = user_no;
	}

	public String getUser_id() {
		return user_id;
	}

	public void setUser_id(String user_id) {
		this.user_id = user_id;
	}

	public String getUser_pw() {
		return user_pw;
	}

	public void setUser_pw(String user_pw) {
		this.user_pw = user_pw;
	}
	
	public String getUser_newestpw() {
		return user_newestpw;
	}


	public void setUser_newestpw(String user_newestpw) {
		this.user_newestpw = user_newestpw;
	}
	

	public String getUser_newestpw_check() {
		return user_newestpw_check;
	}


	public void setUser_newestpw_check(String user_newestpw_check) {
		this.user_newestpw_check = user_newestpw_check;
	}


	public String getUser_name() {
		return user_name;
	}

	public void setUser_name(String user_name) {
		this.user_name = user_name;
	}

	public String getUser_email() {
		return user_email;
	}

	public void setUser_email(String user_email) {
		this.user_email = user_email;
	}

	public String getUser_role() {
		return user_role;
	}

	public void setUser_role(String user_role) {
		this.user_role = user_role;
	}

	public String getUser_photo() {
		return user_photo;
	}

	public void setUser_photo(String user_photo) {
		this.user_photo = user_photo;
	}

	public String getUser_active() {
		return user_active;
	}

	public void setUser_active(String user_active) {
		this.user_active = user_active;
	}
	
	public String getUser_distinct() {
		return user_distinct;
	}


	public void setUser_distinct(String user_distinct) {
		this.user_distinct = user_distinct;
	}


	public Date getUser_regdate() {
		return user_regdate;
	}

	public void setUser_regdate(Date user_regdate) {
		this.user_regdate = user_regdate;
	}
	public FriendDto getFriendDto() {
		return friendDto;
	}
	public void setFriendDto(FriendDto friendDto) {
		this.friendDto = friendDto;
	}
	

}

16. FileUploadController.java

package com.minibean.timewizard.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

import com.minibean.timewizard.model.biz.FileUploadBiz;
import com.minibean.timewizard.model.dto.FileUploadDto;
import com.minibean.timewizard.model.dto.UserInfoDto;
import com.minibean.timewizard.utils.file.FileUploadUtils;
import com.minibean.timewizard.utils.file.FileValidator;

@RestController
@RequestMapping(value="/file")
public class FileUploadController {
	
	@Autowired
	private FileValidator fileValidator;
	@Autowired
	private FileUploadUtils fileUploadUtils;
	@Autowired
	private FileUploadBiz fileUploadBiz;
	
	private Logger logger = LoggerFactory.getLogger(FileUploadController.class);

	@PostMapping(value="/list/{user_no}")
	public List<FileUploadDto> selectVideoList(HttpSession session, @PathVariable int user_no) {
		List<FileUploadDto> list = fileUploadBiz.selectVideoList(user_no);
		logger.info(">> [CONTROLLER-FILEUPLOAD] select video list - " + user_no);
		return list;
	}
	
	@PostMapping(value="/one/{user_no}")
	public FileUploadDto selectImageOne(HttpSession session, @PathVariable int user_no) {
		FileUploadDto dto = fileUploadBiz.selectImageOne(user_no);
		logger.info(">> [CONTROLLER-FILEUPLOAD] select image one - " + user_no);
		return dto;
	}
	
	@PostMapping(value="/upload")
	public Map<String, Boolean> fileUpload(HttpServletRequest request, FileUploadDto uploadFile, BindingResult result) {
		
		logger.info(">> [CONTROLLER-FILEUPLOAD] upload");
		
		Map<String, Boolean> answer = new HashMap<String, Boolean>();
		
		fileValidator.validate(uploadFile, result);
		if (result.hasErrors()) {
			answer.put("result",false);
			return answer;
		}
		
		MultipartFile file = uploadFile.getFile();
		String fileExtension = FilenameUtils.getExtension(file.getOriginalFilename());
		String uploadedName = fileUploadUtils.makeRandomName() + "." + fileExtension;
		
		FileUploadDto fileObj = new FileUploadDto();
		fileObj.setFile_name(uploadedName);
		
		InputStream inputStream = null;
		OutputStream outputStream = null;
		
		try {
			
			inputStream = file.getInputStream();
			String uploadPath = WebUtils.getRealPath(request.getSession().getServletContext(), "/resources/image");
			logger.info("\n* uploaded file path : " + uploadPath 
					+ "\n* file original name : " + file.getOriginalFilename());
			
			File storage = new File(uploadPath);
			if (!storage.exists()) {
				storage.mkdir();
			}
			File newFile = new File(uploadPath + "/" + uploadedName);
			if (!newFile.exists()) {
				newFile.createNewFile();
			}
			outputStream = new FileOutputStream(newFile);
			
			int read = 0;
			byte[] b = new byte[(int)file.getSize()];
			
			while((read=inputStream.read(b)) != -1) {
				outputStream.write(b, 0, read);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				inputStream.close();
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		answer.put("result",true);
		
		FileUploadDto dto = new FileUploadDto();
		dto.setUser_no(((UserInfoDto)request.getSession().getAttribute("login")).getUser_no());
		dto.setFile_name(uploadedName);
		if (fileExtension.equalsIgnoreCase("jpg") || fileExtension.equalsIgnoreCase("jpeg") 
			|| fileExtension.equalsIgnoreCase("png") || fileExtension.equalsIgnoreCase("gif")) {
			dto.setFile_type("I");
		} else if (fileExtension.equalsIgnoreCase("mp4")) {
			dto.setFile_type("V");
		}
		
		int res = fileUploadBiz.insert(dto);
		logger.info(">> [CONTROLLER-FILEUPLOAD] success?: " + ((res == 1)?"yes":"no"));
		
		return answer;
	} 
	
	@RequestMapping(value="/download/{file_no}")
	public byte[] fileDownload(HttpServletRequest request, HttpServletResponse response, @PathVariable int file_no) {
//	public Map<String, Object> fileDownload(HttpServletRequest request, HttpServletResponse response, @PathVariable int file_no) {

		
		logger.info(">> [CONTROLLER-FILEUPLOAD] download");
		
		Map<String, Object> answer = new HashMap<String, Object>();
		
		FileUploadDto dto = fileUploadBiz.selectOne(file_no);
		String extension = FilenameUtils.getExtension(dto.getFile_name());
		String mime_front = (dto.getFile_type().equals("P"))?"image":"video";
		String mime_back = (extension.toLowerCase().equals("jpg"))?"jpeg":extension.toLowerCase();
		answer.put("mime", mime_front + "/" + mime_back);
		answer.put("extension", extension);
		
		byte[] down = null;
		
		try {
			String uploadPath = WebUtils.getRealPath(request.getSession().getServletContext(), "/resources/image");
			File file = new File(uploadPath + "/" + dto.getFile_name());
			
			down = FileCopyUtils.copyToByteArray(file);
			String filename = new String(file.getName().getBytes(), "8859_1");
			
			response.setHeader("Content-Disposition", "attachment; filename=\""+filename +"\"");
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		answer.put("bytes", down);

		return down;
//		return answer;
		
	}
	
}

17. file_upload.js (이건 필요하지 않은 부분이나 mypage.js 만들 때 참고했던 다른 팀원의 코드이므로 기록해둠.)

function uploadFile(){
	let fileInput = document.querySelector("[name=file]");
	let file = fileInput.files[0];
	let formData = new FormData();
	formData.append("file",file);
	const xhr = new XMLHttpRequest();
	xhr.open("POST","/timewizard/file/upload");
	xhr.send(formData);
	xhr.onreadystatechange = () => {
		if (xhr.readyState == 4 && xhr.status == 200){
			if (JSON.parse(xhr.responseText).result == true){
				selectOne(user_no);
			}
		}
	}
}

function downloadFile(file_no){
	const xhr = new XMLHttpRequest();
	xhr.open("POST","/timewizard/file/download/"+file_no);
	xhr.send();
	xhr.onreadystatechange = () => {
		if (xhr.readyState == 4 && xhr.status == 200){
			if (xhr.responseText != null && xhr.responseText  != "" && xhr.responseText != '[]'){
				/*
				let item = JSON.parse(xhr.responseText);
				console.log(item);
				let blob = new Blob([item.bytes], {type: item.mime});
				console.log(blob);
				let link = document.createElement("a");
				link.href = window.URL.createObjectURL(blob);
				let fileName = "timewizard_" + new Date().getTime();
				link.download = fileName + "." + item.extension;
				link.click();
				 */
				return xhr.responseText;
			}
		}
	}
}

function selectList(user_no){
	let filesArea = document.querySelector(".files__area");
	filesArea.innerHTML = "";
	const xhr = new XMLHttpRequest();
	xhr.open("POST","/timewizard/file/list/"+user_no);
	xhr.send();
	xhr.onreadystatechange = () => {
		if (xhr.readyState == 4 && xhr.status == 200){
			if (xhr.responseText != null && xhr.responseText != "" && xhr.responseText != '[]'){
				console.log(JSON.parse(xhr.responseText));
				let files = JSON.parse(xhr.responseText);
				let i = 0;
				
				let files_div = document.createElement("div");
				files_div.setAttribute("class","files");
				
				for (i = 0; i < files.length; i++){
					let file_div = document.createElement("div");
					file_div.setAttribute("class","file");
					
					let number_cell = document.createElement("div");
					number_cell.setAttribute("class","cell number__cell");
					let number_cell_span = document.createElement("span");
					number_cell_span.setAttribute("class", "number");
					number_cell_span.textContent = i + 1;
					number_cell.appendChild(number_cell_span);
					
					/*
					let title_cell = document.createElement("div");
					title_cell.setAttribute("class","cell title__cell");
					let title = document.createElement("p");
					title.textContent = files[i].file_name;
					title_cell.appendChild(title);
					*/
					
					let title_cell = document.createElement("div");
					title_cell.setAttribute("class","cell title__cell");
					let title = document.createElement("p");
					title.textContent = files[i].file_regdate;
					/* 형식 체크하기 */
					title_cell.appendChild(title);
					
					let download_cell = document.createElement("div");
					download_cell.setAttribute("class","cell download__cell");
					/*
					if (user_no == files[i].user_no){
						download_cell.setAttribute("onclick","downloadFile("+ files[i].file_no + ");")
					}
					let file_download = document.createElement("i");
					file_download.setAttribute("class","fas fa-file-download");
					download_cell.appendChild(file_download);
					 */
					let form = document.createElement("form");
					form.setAttribute("action","/timewizard/file/download/"+files[i].file_no);
					form.setAttribute("method","POST");
					let submit = document.createElement("input");
					submit.setAttribute("type","submit");
					submit.setAttribute("value","download");
					form.appendChild(submit);
					download_cell.appendChild(form);
					
					file_div.appendChild(number_cell);
					file_div.appendChild(title_cell);
					file_div.appendChild(download_cell);
					files_div.appendChild(file_div)
				}
				filesArea.appendChild(files_div);
				
			} else if (xhr.responseText == '[]'){
				filesArea.textContent = "저장된 파일이 없습니다.";
			}
		}
	}
}

function selectOne(user_no){
	let filesArea = document.querySelector(".files__area");
	filesArea.innerHTML = "";
	const xhr = new XMLHttpRequest();
	xhr.open("POST","/timewizard/file/one/"+user_no);
	xhr.send();
	xhr.onreadystatechange = () => {
		if (xhr.readyState == 4 && xhr.status == 200){
			console.log(xhr.responseText);
			if (xhr.responseText != null && xhr.responseText != ""){
				let file = JSON.parse(xhr.responseText);
				
				let files_div = document.createElement("div");
				files_div.setAttribute("class","files");
				
				let file_div = document.createElement("div");
				file_div.setAttribute("class","file");
					
				let number_cell = document.createElement("div");
				number_cell.setAttribute("class","cell number__cell");
				let number_cell_span = document.createElement("span");
				number_cell_span.setAttribute("class", "number");
				number_cell_span.textContent = 1;
				number_cell.appendChild(number_cell_span);
				
				let title_cell = document.createElement("div");
				title_cell.setAttribute("class","cell title__cell");
				let title = document.createElement("p");
				title.textContent = file.file_name;
				title_cell.appendChild(title);
				
				let download_cell = document.createElement("div");
				download_cell.setAttribute("class","cell download__cell");
				
				let form = document.createElement("form");
				form.setAttribute("action","/timewizard/file/download/"+file.file_no);
				form.setAttribute("method","POST");
				let submit = document.createElement("input");
				submit.setAttribute("type","submit");
				submit.setAttribute("value","download");
				form.appendChild(submit);
				download_cell.appendChild(form);
				
				file_div.appendChild(number_cell);
				file_div.appendChild(title_cell);
				file_div.appendChild(download_cell);
				files_div.appendChild(file_div)
				filesArea.appendChild(files_div);
				
			} else if (xhr.responseText == "" || xhr.responseText == null){
					filesArea.textContent = "저장된 파일이 없습니다.";
			}
		}
	}
}

18. MyPageController.java

package com.minibean.timewizard.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

import com.minibean.timewizard.model.biz.FileUploadBiz;
import com.minibean.timewizard.model.biz.PayBiz;
import com.minibean.timewizard.model.biz.UserInfoBiz;
import com.minibean.timewizard.model.dto.FileUploadDto;
import com.minibean.timewizard.model.dto.PayDto;
import com.minibean.timewizard.model.dto.UserInfoDto;
import com.minibean.timewizard.utils.file.FileUploadUtils;
import com.minibean.timewizard.utils.file.FileValidator;

@Controller
public class MypageController {
	
	private Logger logger = LoggerFactory.getLogger(MypageController.class);
	
	@Autowired
	private UserInfoBiz userinfoBiz;
	@Autowired
	private FileUploadBiz fileUploadBiz;
	@Autowired
	private FileValidator fileValidator;
	@Autowired
	private FileUploadUtils fileUploadUtils;
	@Autowired
	private PayBiz payBiz;
	
	@RequestMapping("/mypage")
	public String Mypage(HttpSession session, Model model) {
		logger.info("[mypage]");
		
		UserInfoDto userinfodto = (UserInfoDto)session.getAttribute("login");
	
			PayDto dto = payBiz.selectOne(userinfodto.getUser_no());
			if(dto == null) {
				int res = payBiz.insertPay(new PayDto(userinfodto.getUser_no(),"N",0));
				if (res > 0){
					dto = payBiz.selectOne(userinfodto.getUser_no());
				}
				model.addAttribute("dto",dto);
				logger.info("mypage user_no : " + userinfodto.getUser_no());
				return "mypage";
			}
		model.addAttribute("dto",dto);
		return "mypage";
	}
	

	/* 유저 탈퇴 */
	@RequestMapping("/userdeletepage")
	public String UserDeletePage(Model model, @RequestParam int user_no) {
		logger.info("[user delete page]");

		model.addAttribute("dto", userinfoBiz.selectOne(user_no));
		
		return "userdeletepage";
	}
	
	@RequestMapping("/userdeleteres")
	public void UserDelete(HttpServletResponse response, UserInfoDto dto, HttpSession session, @RequestParam int user_no) throws Exception {
		logger.info("[user delete Reusult]");
		
		UserInfoDto user = (UserInfoDto) session.getAttribute("login");
		String user_pw = user.getUser_pw();
		String new_pw = dto.getUser_pw();
		
		//비밀번호 불일치로 탈퇴 실패
		if(!(user_pw.equals(new_pw))) {
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter out = response.getWriter();
			out.println("<script>alert('비밀번호가 불일치해서 탈퇴에 실패했습니다.'); location.href='/timewizard/mypage'</script>");
			out.flush();

		} else {
		
			int res = userinfoBiz.delete(user_no);
			
			if(res != 0) {
				System.out.println("탈퇴 성공");
			} else {
				System.out.println("탈퇴 실패");
			}
			
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter out = response.getWriter();
			out.println("<script>alert('탈퇴에 성공하셨습니다.'); location.href='/timewizard/login/loginform';</script>");
			out.flush();
			session.invalidate();
		}
	}
	
	
	/* 비밀번호 변경 */
	@RequestMapping("/userpwchange")
	public String UserPwChange(Model model, @RequestParam int user_no) {
		logger.info("[user password change]");

		model.addAttribute("dto", userinfoBiz.selectOne(user_no));
		
		return "userpwchange";
		
	}
	
	@RequestMapping("/userpwchangeres")
	public void UserPwChangeRes(HttpServletResponse response, HttpSession session, UserInfoDto dto, @RequestParam String user_newestpw_check, @RequestParam String user_newestpw, @RequestParam int user_no) throws Exception {
		logger.info("[user pw change Result]");
		
		UserInfoDto user = (UserInfoDto) session.getAttribute("login");
		// 기존 패스워드
		String user_pw = user.getUser_pw();
		// 사용자가 비밀번호 변경 페이지의 '기존 패스워드' 칸에 입력한 암호
		String new_pw = dto.getUser_pw();
		
		// '새 비밀번호'와 '새 비밀번호 확인'을 setter에 담아주고 get으로 가져옴
		dto.setUser_newestpw(user_newestpw);
		dto.setUser_newestpw_check(user_newestpw_check);
		String newestpw = dto.getUser_newestpw();
		String newestpwcheck = dto.getUser_newestpw_check();
		
		//기존 비밀번호 불일치로 암호 변경 실패
		if(!(user_pw.equals(new_pw))) {
			
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter out = response.getWriter();
			out.println("<script>alert('기존 패스워드가 불일치합니다. 암호 변경에 실패했습니다.'); location.href='/timewizard/mypage'</script>");
			out.flush();
			
		} else {
			
			// 새 비밀번호와 새 비밀번호 확인이 일치하면
			if (newestpw.equals(newestpwcheck)) {
			
			logger.info("user_newestpw :"+newestpw);
			logger.info("user_no :"+user_no);
			
			// 비밀번호 변경
			int res = userinfoBiz.pwChangeRes(dto);
			  
			if(res != 0) {
				
				System.out.println("암호 변경 성공");
				response.setContentType("text/html; charset=UTF-8");
				PrintWriter out = response.getWriter();
				out.println("<script>alert('비밀번호가 변경되었습니다. 변경된 비밀번호로 다시 로그인하실 수 있습니다.'); location.href='/timewizard/login/loginform';</script>");
				out.flush();
				session.invalidate();
				}
			
			} else {
				
				System.out.println("암호 변경 실패");
				response.setContentType("text/html; charset=UTF-8");
				PrintWriter out = response.getWriter();
				out.println("<script>alert('새 비밀번호와 새 비밀번호 확인이 일치하지 않습니다. 암호 변경에 실패했습니다.'); location.href='/timewizard/mypage'; </script>");
				out.flush();
			}
		}
	}
	
	@RequestMapping(value="/profileupload")
	@ResponseBody
	public void fileUpload(HttpServletResponse response ,HttpServletRequest request, Model model, @ModelAttribute("filedto") FileUploadDto fileuploadDto, BindingResult result) {
		logger.info("[user profile change]");
		
		UserInfoDto userInfoDto = new UserInfoDto();
		
		MultipartFile file = fileuploadDto.getFile();
		String fileExtension = FilenameUtils.getExtension(file.getOriginalFilename());
		String uploadedName = fileUploadUtils.makeRandomName() + "." + fileExtension;
		
		logger.info("업로디드 네임 :"+uploadedName);
		FileUploadDto fileObj = new FileUploadDto();
		fileObj.setFile_name(uploadedName);
		
		InputStream inputStream = null;
		OutputStream outputStream = null;
		
		try {
			
			inputStream = file.getInputStream();
			String uploadPath = WebUtils.getRealPath(request.getSession().getServletContext(), "/resources/image");
			logger.info("\n* 업로디드 경로 : " + uploadPath 
					+ "\n* file original name : " + file.getOriginalFilename());
			
			File storage = new File(uploadPath);
			if (!storage.exists()) {
				storage.mkdir();
			}
			File newFile = new File(uploadPath + "/" + uploadedName);
			if (!newFile.exists()) {
				newFile.createNewFile();
			}
			outputStream = new FileOutputStream(newFile);
			
			int read = 0;
			byte[] b = new byte[(int)file.getSize()];
			
			while((read=inputStream.read(b)) != -1) {
				outputStream.write(b, 0, read);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				inputStream.close();
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		FileUploadDto dto = new FileUploadDto();
		dto.setUser_no(((UserInfoDto)request.getSession().getAttribute("login")).getUser_no());
		dto.setFile_name(uploadedName);

		if (fileExtension.equalsIgnoreCase("jpg") || fileExtension.equalsIgnoreCase("jpeg") 
			|| fileExtension.equalsIgnoreCase("png") || fileExtension.equalsIgnoreCase("gif")) {
			dto.setFile_type("I");
		} else if (fileExtension.equalsIgnoreCase("mp4")) {
			dto.setFile_type("V");
		}
		
		int res = fileUploadBiz.insert(dto);
		logger.info(">> [CONTROLLER-FILEUPLOAD] success?: " + ((res == 1)?"yes":"no"));
		
		// 프로필 사진을 등록하지 않은 디폴트값은 user_photo=null임. user_photo에 insert된 file이 서버에 랜덤으로 저장[FileUploadUtils 클래스 참고]된 name을 setting 해줌. 
		userInfoDto.setUser_photo(dto.getFile_name());
		userInfoDto.setUser_no(dto.getUser_no());
		logger.info("파일 이름: {} \n유저 번호: {}",dto.getFile_name(), userInfoDto.getUser_no());
		// user_photo의 값을 null에서 윗줄의 값으로 update 해줌.
		int res2 = userinfoBiz.profileChange(userInfoDto);
		 
		logger.info("[user profile change] success?: " + ((res2 == 1)?"yes":"no"));
		request.getSession().setAttribute("login", userinfoBiz.selectOne(userInfoDto.getUser_no()));
		UserInfoDto test = (UserInfoDto)request.getSession().getAttribute("login");
		logger.info(test.getUser_photo());
		PrintWriter out;
		try {
			out = response.getWriter();
			out.print("<script type='text/javascript'>location.href='/timewizard/mypage';</script>");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	

	
	
	
	/* NAME, EMAIL 변경 */
	@RequestMapping("/userInfoChange")
	public String userInfoChange(HttpSession session ,UserInfoDto dto, @RequestParam int user_no, @RequestParam String user_name, @RequestParam String user_email) {
		logger.info("[user name or email change]");
		
		logger.info("user_no : "+user_no);
		logger.info("user_name : "+user_name);
		logger.info("user_email : "+user_email);
		
		 int res = userinfoBiz.userInfoChange(dto);
		 
		  if(res != 0) {
			  // 값 변경에 성공하는 경우 login session에 바뀐 값을 새로 넣어줌. 이 코드가 있어야 바뀐 값이 화면에 뿌려짐.
			  session.setAttribute("login", userinfoBiz.selectOne(dto.getUser_no()));
			  logger.info("이름, 이메일 변경 성공");
			  System.out.println();
		  } else {
			  System.out.println("이름, 이메일 변경 실패");
		  }
		
		return "redirect:mypage";
		
	}
	
	
	//pay
	@RequestMapping("/pay")
	public String pay(int user_no, String price, String pay_name) {
		logger.info("[pay controller]");
		
		PayDto dto = payBiz.selectOne(user_no);
		
		//멤버쉽결제
		if(pay_name.equals("membership")) {
			logger.info("pay_name01010101 : "+pay_name);
			int res = payBiz.updateMembership(new PayDto(user_no,"Y",0));
			logger.info("res : "+res);
			logger.info("price : "+price);
			logger.info("pay_name : "+pay_name);
			if(res > 0) {
				return "redirect:mypage";
			}else {
				return "mypage";
			}
			
		}else {  //timelapse결제
			logger.info("pay_name020202 : "+pay_name);
			if(price.equals("1000")) {
				logger.info("price01 : "+price);
				int res = payBiz.updateTimelapse(new PayDto(user_no, null, dto.getTimelapse()+1));
				logger.info("res : "+res);
				if(res > 0) {
					return "redirect:mypage";
				}
			}else if(price.equals("5000")) {
				logger.info("price02 : "+price);
				int res = payBiz.updateTimelapse(new PayDto(user_no, null, dto.getTimelapse()+5));
				if(res > 0) {
					return "redirect:mypage";
				}

			}else {
				logger.info("price03 : "+price);
				int res = payBiz.updateTimelapse(new PayDto(user_no, null, dto.getTimelapse()+10));
				if(res > 0) {
					return "redirect:mypage";
				}
			}
			//
			return "redirect:mypage";
		}
	
		
	}

}

19. mypage.jsp

<%@page import="com.minibean.timewizard.model.dto.UserInfoDto"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE>
<html>
<head>
<meta charset="UTF-8">
<title>mypage</title>

<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&family=Source+Sans+Pro:wght@200;400&family=Staatliches&display=swap" rel="stylesheet">
<link href="resources/css/mypage.css" rel="stylesheet">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="resources/js/mypage.js" defer></script>
<link href="/timewizard/css/actionpage.css" rel="stylesheet">
<script src="https://kit.fontawesome.com/3049a69bf8.js" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdn.iamport.kr/js/iamport.payment-1.1.5.js"></script>
<script type="text/javascript">

const elImage = document.querySelector("#reviewImageFileOpenInput");
elImage.addEventListener("change", (evt) => {
  const image = evt.target.files[0];
  if(!validImageType(image)) { 
    console.warn("invalide image file type");
    return;
  }
});

function valideImageType(image) {
  const result = ([ 'image/jpeg',
                    'image/png',
                    'image/jpg' ].indexOf(image.type) > -1);
  return result;
}

//결제 pay
let user_no = ${login.user_no};
let user_name = ${login.user_name};
let membership;

function pay(e){
	var IMP = window.IMP;
	IMP.init('imp26998959');
	let name = $(e).attr("name");
	let price = $(e).val();
	IMP.request_pay({
	    pg : 'inicis', // version 1.1.0부터 지원.
	    pay_method : 'card',
	    merchant_uid : "timewizard-" + new Date().getTime(),
	    name : name, //상품이름
	    amount : price, //판매 가격
	    buyer_email : '${login.user_email}',
	    buyer_name : '${login.user_name}',
	}, function(rsp) {
	    if ( rsp.success ) {
	    	
	    	location.href="/timewizard/pay?user_no="+${login.user_no}+"&pay_name="+rsp.name+"&price="+rsp.paid_amount;
	        var msg = '결제가 완료되었습니다.';
	       
	    } else {
	        var msg = '결제에 실패하였습니다.';
	        msg += '에러내용 : ' + rsp.error_msg;
	    }
	    alert(msg);
	});
}
	
</script>
</head>

<body>
<%
	UserInfoDto login = (UserInfoDto) session.getAttribute("login");
	int user_no = login.getUser_no();
	String user_photo = (login.getUser_photo() == null) ? "3J1kUZfY.jpg" : login.getUser_photo();
%>
	<div class="mypagebox">
		<div class="mypagemenu" align="center">
			<div class="preview">
            	<!-- 프로필 사진 미리보기 -->
				<img id="frame" src="/timewizard/resources/image/<%=user_photo %>" />
			</div>
            <!-- send 버튼 누르면 프로필 사진 변경됨 -->
			<form:form method="post" enctype="multipart/form-data" modelAttribute="UserInfoDto" action="profileupload">
				<label><input type="file" name="file" class="mypagebtn" accept="image/*" id="image" name="user_photo" /></label>
				<input type="hidden" name="user_no" value="<%=user_no%>" />
				<label><input type="submit" class="mypagebtn" value="send" /></label>
			</form:form>
			
			<form action="userInfoChange">
				<input type="hidden" name="user_no" value="${dto.user_no}">
				<div class="userchange">
					<table>
						<tr>
							<td>ID</td>
							<td><input type="text" name="user_id" size=20 readonly value="${login.user_id }"></td>
						</tr>
						<tr>
							<td>NAME</td>
							<td><input type="text" name="user_name" size=20 value="${login.user_name }"></td>
						</tr>
						<tr>
							<td>EMAIL</td>
							<td><input type="email" name="user_email" size=20 value="${login.user_email }"></td>
						</tr>
						<tr>
							<td colspan="2" align="right">
								<input type="submit" class="submitbox" value="수정" /><br/>
								<a href="userpwchange?user_no=${login.user_no }" class="btndesign">암호변경</a>
								<a href="userdeletepage?user_no=${login.user_no }" class="btndesign">탈퇴</a>
							</td>
						</tr>
					</table>
				</div>
			</form>
		</div>
	
		<div class="files__area" align="center"></div>
		
		<div class="mypagemenu" align="center">
			<form>
			<input type="hidden" name="user_no" value="${login.user_no }">
			<table>
			<c:choose>
			<c:when test="${dto.membership eq 'N' }">  
				<tr>
					<td><b>스트리밍 이용</b></td>
					<td colspan="3" align="center"><input type="button" class="payname"  name="membership" value="9900" onclick="pay(this);"></td>
				</tr>
			</c:when>
			<c:otherwise>
				<tr>
					<td><b>스트리밍 이용</b></td>
					<td colspan="3" align="center"><input type="button" name="membership" value="9900" onclick="pay(this);" disabled></td>
				</tr>
			</c:otherwise>
			</c:choose>
				<tr>
					<td align="center"><b>timelapse</b></td>
					<td align="center">1</td>
					<td align="center">5</td>
					<td align="center">10</td>
				</tr>			
					<tr>
						<td align="center" id="lastcount">( ${dto.timelapse } )</td>	
						<td><input type="button" class="payname" name="timelapse" value="1000" onclick="pay(this);"></td>
						<td><input type="button" class="payname" name="timelapse" value="5000" onclick="pay(this);"></td>
						<td><input type="button" class="payname" name="timelapse" value="9000" onclick="pay(this);"></td>
					</tr>	
			</table>
			</form>
		</div>
		<div class="home"><a href="main"><i class="fas fa-arrow-circle-left" style="color:#263343;"></i></a></div>
	</div>
	
	<script type="text/javascript">
	let uno = ${login.user_no};
	window.addEventListener("DOMContentLoaded", ()=>{
		selectOne(uno);
		selectList(uno)
	});
	</script>


</body>
</html>

20. mypage.js

/* 프로필 이미지 미리보기 */
var image = document.getElementById('image');
var frame = document.getElementById('frame');
image.addEventListener('change', function(e) {
	console.log(e);
	var file = e.target.files[0];
	frame.src = URL.createObjectURL(file);
});