Project/javachip

[2nd Project] 프로필 이미지 수정(JSP, STS)

ParkYeseul 2024. 10. 22. 10:48

마이페이지의 핵심이라고 생각되는 프로필 편집을 하고 있다. 

 

영역이 다 깨져있지만

지금 프로필 이미지 변경을 가능 하도록 만들고 있다. 

 

비밀번호도 유효성에 맞게 변경하도록 했으며, 비밀번호 확인란과 일치 해야만 변경이 된다.

닉네임도 마찬가지로 고유한 값이기 때문에 중복 검사를 필요로 한다.

 

닉네임, 혹은 비밀번호만 변경할 수 있으며 
이 페이지 하단의 회원 탈퇴를 누르면 탈퇴가 된다!
  

마이페이지 양식

 

 

오류로 인해 조금 미뤄두었던 프로필 이미지란을 구현하고 있다.

사진 업로드라니!!

 

사진을 업로드 하면 경로가 어떻게 가는지가 궁금해서 흐름을 한 번 알아보았다.

 

위에 파일 선택 버튼을 누르면 파일창이 뜨고 이미지를 선택할 수 있다.


선택 후 변경하기 버튼을 누르면 Form태그 안에 내용이 서버로 전송된다. 

enctype="multipart/form-data" 이 녀석이 파일 업로드를 처리하기 위한 폼 전송 방식이다.

 

그럼 이미지 파일이 서버로 전송되면서 컨트롤러로 넘어가게 된다.  

 

 

@PostMapping("/updateProcess")
public String updateProcess(
    M_MemberVO vo, 
    @RequestParam("profileImage") MultipartFile profileImage,  // JSP에서 선택된 이미지 파일
    HttpServletRequest request, 
    Model model) {

    // 이미지 파일이 있는지 확인
    if (profileImage != null && !profileImage.isEmpty()) {
        // 서버에 저장될 경로 설정
        String webPath = "/resources/images";  // 실제 저장될 폴더 경로
        String filePath = request.getSession().getServletContext().getRealPath(webPath);  // 실제 파일 저장 경로

        String fileName = profileImage.getOriginalFilename(); // 업로드된 파일 이름
        try {
            File saveFile = new File(filePath, fileName);
            profileImage.transferTo(saveFile);  // 서버 경로에 파일 저장
            vo.setM_profile(webPath + "/" + fileName);  // DB에 저장될 경로 설정
        } catch (IOException e) {
            e.printStackTrace();
            model.addAttribute("fileError", "파일 업로드 중 오류가 발생했습니다.");
            return "Member/m_updateProfile"; // 오류 시 반환할 뷰
        }
    }

    // 이후 로직 처리 (프로필 업데이트 등)
    return "redirect:/MyPage/myPageMain";  // 성공 시 리다이렉트
}

컨트롤러에서 MultipartFile 타입으로 전송된 파일을 받는다.

이 파일은 profileImage 여기 변수에 담기게 된다. 이후 파일을 서버 특정 폴더에 저장해야 한다.

 

profileImage.transferTo(saveFile); 매서드를 사용해서 서버의 특정 폴더에 파일을 저장하게 된다.
서버에 파일을 저장했으면, 이제 DB에 이미지 경로를 저장 해야겠죠? 

vo.setM_profile(webPath + "/" + fileName);  // DB에 저장될 경로 설정한다!

 

DB에 저장된 이미지 경로를 사용해서 웹 페이지에서는 이미지를 표시 할 수 있다. JSP파일에서 경로를 

읽어서 이미지 태그에 출력되는 것.

 

정리해보자면

1. JSP에서 파일 이미지 선택

2. 변경하기 버튼 클릭 후 서버로 전송

3. 서버에 파일을 저장

4. 웹에서 이미지 표시!

 

 

짠! 
ㅋㅋㅋㅋㅋㅋㅋ

 

이제 코드 리뷰를 해보잣! 

 

➰M_MemberController

  // 4. 프로필 이미지 처리
		    if (profileImage != null && !profileImage.isEmpty()) {
		    	System.out.println("Uploaded File Name: " + profileImage.getOriginalFilename());
		    	
		        // 웹 접근 경로
		        String webPath = "/resources/images";
		        // 실제 이미지 파일이 저장되어야 하는 서버 컴퓨터 경로
		        String filePath = "C:/Users/admin/Downloads"; 
		        System.out.println("Actual File Path: " + filePath);  // 실제 경로 확인
		        // 파일 저장 경로 설정
		        String fileName = profileImage.getOriginalFilename();
		        try {
		            File saveFile = new File(filePath, fileName);
		            profileImage.transferTo(saveFile); // 파일 저장
		            vo.setM_profile("/resources/images/" + fileName); // 이미지 경로 설정
		            System.out.println("Profile Image Path: " + vo.getM_profile()); // 경로 로그 확인
		            
		            // DB 업데이트 시도
		            M_MemberVO updatedMember = m_memberServiceImpl.updateProfileImage(vo);
		            if (updatedMember != null) {
		                System.out.println("DB 업데이트 성공: " + updatedMember.getM_profile());
		            } else {
		                System.out.println("DB 업데이트 실패");
		            }

		            
		        } catch (IOException e) {
		            e.printStackTrace();
		            model.addAttribute("fileError", "파일 업로드 중 오류가 발생했습니다.");
		            return viewName;
		        }
		    }

 

if (profileImage != null && !profileImage.isEmpty())

업로드 했는지 확인하는 메소드, 업로드 된 파일이 존재하는 경우에만 처리

 

profileImage.transferTo(saveFile)

실제 파일을 서버의 filePath에 저장

 

m_memberServiceImpl.updateProfileImage(vo)

서비스 계층에서 DB 업데이트 작업을 수행하여 프로필 이미지 업데이트

 

m_memberServiceImpl.updateMember(vo)

DB에 회원 정보를 업데이트 하는 서비스 계층을 호출하여

M_MemberVO객체를 전달 -> 회원 정보를 업데이트


session.removeAttribute() 및 session.setAttribute()

기존 세션에서 회원 정보를 제거하고, 새로운 회원 정보를 세션에 등록하여 업데이트된 정보 유지

 

 

➰M_MemberServiceImpl

@Override
    public M_MemberVO updateProfileImage(M_MemberVO vo) {
        int result = dao.updateProfileImage(vo); // 업데이트 메서드 호출
        return (result > 0) ? dao.getMember(vo.getM_idx()) : null; // 업데이트 성공 시 회원 정보 반환
    }

dao.updateProfileImage(vo)

DAO메서드를 호출하여 DB에서 프로필 이미지를 업데이트하는 작업 수행

vo객체에 저장된 프로필 이미지 경로와 회원 ID 정보를 이용해 업데이트

이 메서드로 업데이트된 행의 개수를 반환.

MyBatis의 update메서드는 기본적으로 영향을 받은 행의 수를 반환하므로 

업데이트가 성공하면 1, 실패하면 0을 반환

 

 

➰M_MemberDAO

	public int updateProfileImage(M_MemberVO vo) {
			return sqlSession.update(MAPPER +".updateProfileImage",vo);
		}

여기서 입력 파라미터는 M_MemberVO객체이고 여기에는 m_profilem, m_idx가 담겨있다.

MyBatis의 sqlSession 객체를 이용해 SQL 업데이트 쿼리를 실행하고,

sqlSession.update는 기본적으로 UPDATE SQL 문을 실행하는 메서드로, 
해당 SQL 쿼리가 성공적으로 실행되었는지 여부를 업데이트된 레코드의 개수로 반환

 

➰M_MemberMapper

<update id="updateProfileImage" parameterType="M_MemberVO">
    UPDATE member
    SET m_profile = #{m_profile}
    WHERE m_idx = #{m_idx}
</update>

 

 

 

➰M_UpdateProfile

    <!-- 왼쪽 프로필 영역 -->
    <div class="profile-section">
    <h4>My BBOL BBOL BBOL</h4>
        <div class="profile-card">
               <img src="${pageContext.request.contextPath}${member.m_profile}" alt="프로필 사진" class="profile-image">
        
        <h3>${member.m_nickname}</h3>
        
         
<a href="${pageContext.request.contextPath}/Member/m_updateProfile">
    <button>프로필 편집</button>
</a>
</div>
</div>

<div class="profile-container">
    <div class="profile-form-container">
        <form action="updateProcess" method="post" enctype="multipart/form-data">
           <!-- 프로필 이미지 표시 및 변경 -->
    <div class="profile-image-section">
       <%-- 프로필 이미지 가 없으면 기본이미지 --%>
       <c:if test="${empty member.m_profile}" >
           <img src="/resources/images/user.png" id="profileImage">
       </c:if>
       <%-- 프로필 이미지 가 있으면 이미지 --%>
       <c:if test="${!empty member.m_profile}" >
           <img src = "${member.m_profile}" id="profileImage">
       </c:if>
   </div>
   <span id="deleteImage">x</span>

   <div class="profile-btn-area">
       <label for="imageInput">이미지 선택</label>
       <input type="file" name="profileImage" id="imageInput" accept="image/*">
  
   </div>
    </div>

 

enctype="multipart/form-data"

파일 업로드를 지원하기 위해 enctype 설정

없으면 파일 업로드가 이루어지지 않는다. 


이렇게 프로필 편집 끄읏! 
아이디 비밀번호 찾기를 바로 이어서 해볼 예정이닷!!

 

 


 

어제 밤부터 먹고 싶었던

메론빵과 소보로 빵을 학원에 오자마자 냠하니까

오류 없이 스무스하게 진행 된 것 같은 기분이 드는데

기분 탓인가~👶