Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- for문
- 상수
- IntelliJ IDEA
- 인텔리제이 한글 깨짐 해결법
- JAVA객체지향
- Thread
- 자바 멀티스레딩
- Java
- 연관관계
- continue문
- 집합관계
- 메서드 오버로딩
- 인텔리제이 기초 설정
- java변수
- break문
- function
- While
- 생성자
- 시스템 환경 변수 편집
- 형 변환
- 접근제어지시자
- JAVA기초
- multi-threading
- 포함관계
- 메서드
- 컴파일
- this예약어
- OPP개념
- Java데이터 타입
- 반복문
Archives
- Today
- Total
최원종의 개발 블로그
V13-6 회원 정보 수정 기능 수정 본문

User 코드
// 머스태치 화면에서 사용할 편의 메서드 3
public boolean isLocal() {
// true -> 이메일 가입자를 의미 함
return this.oAuthProvider == OAuthProvider.LOCAL;
}
detail.mustache 코드
{{> layout/header}}
<div class="container p-5 flex-grow-1">
<div class="card">
<div class="card-header">마이프로필</div>
<div class="card-body">
<!-- 프로필 이미지 start -->
<div class="text-center mb-4">
{{#user.profileImage}}
<!-- 회원 가입시 로컬 가입자 -->
<img class="rounded-circle" src="{{user.profilePath}}" alt="프로필이미지"
style="width:200px; height:200px"/>
{{#user.local}}
<div class="mt-2">
<form action="/user/profile-image/delete" method="post">
<button type="submit" class="btn btn-sm btn-danger"
onclick="return confirm('프로필 사진을 삭제할까요?')">프로필 사진 삭제</button>
</form>
</div>
{{/user.local}}
{{/user.profileImage}}
{{^user.profileImage}}
<div class="rounded-circle bg-secondary d-inline-flex
justify-content-center align-items-center border"
style="width:200px; height:200px;">
<span>프로필 사진 없음</span>
</div>
{{/user.profileImage}}
</div>
<!-- 프로필 이미지 end -->
<div class="mb-3">
<label class="form-label fw-bold">사용자명</label>
<p class="form-control-plaintext">{{user.username}}</p>
</div>
<div class="mb-3">
<label class="form-label fw-bold">이메일</label>
{{#user.email}}
<p class="form-control-plaintext">{{user.email}}</p>
{{/user.email}}
</div>
<div class="mb-3">
<label class="form-label fw-bold">가입일</label>
<p class="form-control-plaintext">{{user.createdAt}}</p>
</div>
<div class="mb-3">
<a href="/user/update-form" class="btn btn-primary" >회원정보 수정</a>
<a href="/board/list" class="btn btn-secondary" >게시글 목록</a>
</div>
</div>
</div>
</div>
{{> layout/footer}}
update-form.mustache 코드
{{> layout/header}}
<div class="container p-5 flex-grow-1">
<div class="card">
<div class="card-header"><b>회원정보수정</b></div>
<div class="card-body">
<!-- 프로필 이미지 start -->
<div class="text-center mb-4">
{{#user.profileImage}}
<img class="rounded-circle" src="{{user.profilePath}}" alt="프로필이미지"
style="width:200px; height:200px"/>
{{#user.local}}
<div class="mt-2">
<form action="/user/profile-image/delete" method="post">
<button type="submit" class="btn btn-sm btn-danger"
onclick="return confirm('프로필 사진을 삭제할까요?')">프로필 사진 삭제</button>
</form>
</div>
{{/user.local}}
{{/user.profileImage}}
{{^user.profileImage}}
<div class="rounded-circle bg-secondary d-inline-flex
justify-content-center align-items-center border"
style="width:200px; height:200px;">
<span>프로필 사진 없음</span>
</div>
{{/user.profileImage}}
</div>
<!-- 프로필 이미지 end -->
<!-- 이미지 업로드 시 반드시 multipart/form-data 선언 -->
<form action="/user/update" method="post" enctype="multipart/form-data">
<div class="mb-3">
<input type="text" class="form-control" name="username" value="{{user.username}}" disabled>
</div>
{{#user.local}}
<div class="mb-3">
<input type="password" class="form-control" name="password" value="" >
</div>
{{#user.email}}
<div class="mb-3">
<input type="text" class="form-control" name="email" value="{{user.email}}" disabled>
</div>
{{/user.email}}
<!-- 프로필 이미지 등록 필드(선택 사항) -->
<div class="mb-3">
<label for="profileImage" class="form-label">프로필 사진(선택사항)</label>
<input type="file" id="profileImage" class="form-control" name="profileImage" accept="image/*" >
<small class="form-text text-muted">이미지 파일만 업로드 가능합니다(JPG, PNG, GIF 등)</small>
<small class="form-text text-muted d-block mt-1">⭐ 프로필 사진을 등록하지 않아도 회원 가입 가능 </small>
</div>
{{/user.local}}
<button class="btn btn-primary form-control">회원정보수정</button>
</form>
</div>
</div>
</div>
{{> layout/footer}}
UserController 수정 코드
UpdateDTO 에 기존 세션에서 가져와 주입한 부분 제거, 및 유효성 검사 제거
// 회원 정보 수정 기능 요청
@PostMapping("/user/update")
public String updateProc(UserRequest.UpdateDTO updateDTO, HttpSession session) {
// 회원 정보 수정 요청시 기본 비밀번호 null 이고 프로필 이미지만 수정 요청
User sessionUser = (User) session.getAttribute(Define.SESSION_USER);
User updateUser = userService.회원정보수정(sessionUser.getId(), updateDTO);
session.setAttribute(Define.SESSION_USER, updateUser);
return "redirect:/";
}
UserService 수정 코드
UserService 에 회원 정보 수정 로직 변경
/**
* 사용자 정보 수정 처리 (프로필 업데이트)
* @param id (User PK)
* @param updateDTO (사용자가 요청한 데이터)
* @return User
*/
@Transactional
public User 회원정보수정(Integer id, UserRequest.UpdateDTO updateDTO) {
String newPassword = null;
String newProfileImageFilename = null;
// 1. 항상 조회 부터
User userEntity = userRepository.findById(id).orElseThrow(
() -> new Exception404("사용자를 찾을 수 없습니다"));
// 2. 수정 권한 확인
if(!userEntity.getId().equals(id)) {
throw new Exception403("회원정보 수정 권한이 없습니다");
}
// 3. 로직 처리 1 - 사용자가 비밀번호를 입력 했을 경우 갱신
if(updateDTO.getPassword() != null && !updateDTO.getPassword().isBlank()) {
// 여기서 유효성 검사 해야 됨.
updateDTO.validate();
String rawPassword = updateDTO.getPassword();
updateDTO.setPassword(passwordEncoder.encode(rawPassword));
} else {
updateDTO.setPassword(null);
}
// 4. 로직 처리 2 - 사용자가 새로운 이미지를 등록했을 경우
if(updateDTO.getProfileImage() != null && !updateDTO.getProfileImage().isEmpty()) {
try {
if(!FileUtil.isImageFile(updateDTO.getProfileImage())) {
throw new Exception400("이미지 파일만 업로드 가능합니다");
}
// 새 이미지 로컬 폴더에 저장 ( 중복되지 않을 이미지 파일 이름을 리턴)
newProfileImageFilename = FileUtil.saveFile(updateDTO.getProfileImage(), FileUtil.IMAGES_DIR);
updateDTO.setProfileImageFileName(newProfileImageFilename);
// 기존 이미지 파일 삭제 해야 함(로컬에 계속 파일 쌓임)
String oldProfileImageFileName = userEntity.getProfileImage();
if(oldProfileImageFileName != null) {
FileUtil.deleteFile(oldProfileImageFileName, FileUtil.IMAGES_DIR);
}
} catch (IOException e) {
throw new Exception400("파일 저장에 실패");
}
} else {
updateDTO.setProfileImageFileName(userEntity.getProfileImage());
}
// 더티 체킹
userEntity.update(updateDTO);
return userEntity;
}
User 엔티티 수정
User 엔티티에 코드update() 메서드 수정
// 편의 기능 추가 - 회원 정보 수정
public void update(UserRequest.UpdateDTO updateDTO) {
if(updateDTO.getPassword() != null) {
// 암호화 변경되어 들어 옴
this.password = updateDTO.getPassword();
}
if(updateDTO.getProfileImageFileName() != null ) {
// 신규 파일 생성해서 들어 옴
this.profileImage = updateDTO.getProfileImageFileName();
}
}'Spring boot 입문 > Spring boot 입문 -1' 카테고리의 다른 글
| V15-1 회원가입시 이메일 인증 처리 (0) | 2026.06.09 |
|---|---|
| V14 소셜로그인(카카오) 리팩토링 (0) | 2026.06.09 |
| V13-5 env 파일에 카카오 회원가입 비번 설정 (0) | 2026.06.08 |
| V13-4 마이페이지 소셜 이미지 출력하기 위한 코드 수정 (0) | 2026.06.02 |
| V13-3 회원 가입시 출처 관리 (로컬, 소셜) (0) | 2026.06.02 |
