반응형
profile.html
- profile-img-wrap story-border 를 클릭했을때 popup 메소드가 호출되면서 modal-image 가 팝업된다.
- 이 modal-image의 '사진업로드'를 클릭하면 profileImageUpload() 함수가 호출된다.
- profileImageUpload 함수에 페이지 유저의 아이디와 로그인 유저 아이디를 전달한다.
...
<div class="profile-left">
<div class="profile-img-wrap story-border"
onclick="popup('.modal-image')">
<form id="userProfileImageForm">
<input type="file" name="profileImageFile" style="display: none;"
id="userProfileImageInput" />
</form>
<img class="profile-image" src="" th:src="*{profileImageUrl}"
onerror="this.src='/images/person.jpeg'" id="userProfileImage" />
</div>
</div>
...
<!--프로필사진 바꾸기 모달-->
<div class="modal-image" onclick="modalImage()">
<div class="modal">
<p>프로필 사진 바꾸기</p>
<button onclick="profileImageUpload()" th:onclick="|profileImageUpload('${dto.user.id}','${#authentication.principal.user.id}')|">사진 업로드</button>
<button onclick="closePopup('.modal-image')">취소</button>
</div>
</div>
profile.js
- 페이지주인 아이디와 로그인 유저 아이드를 받는다.
- 페이지 유저 아이디랑 로그인 유저가 동일하다면 자동으로 userProfileImageInput 부분을 클릭시킨다.
1. 서버에 이미지 전송
- userProfileImageForm의 0번째 요소를 찾아서 profileImageForm변수에 넣어준다.
- ajax로 이 데이터를 전송하려면 FormData로 감싸야 한다.
=>profileImageForm은 폼테그 그 자체고그것을 FormData에 넣으면 값들만 담긴다고 생각하면 된다.
function profileImageUpload(pageUserId, principalId) {
if(pageUserId != principalId){
alert("프로필 사진을 수정할 수 없는 유저입니다.");
return;
}
$("#userProfileImageInput").click();
$("#userProfileImageInput").on("change", (e) => {
let f = e.target.files[0];
if (!f.type.match("image.*")) {
alert("이미지를 등록해야 합니다.");
return;
}
// 서버에 이미지를 전송
let profileImageForm = $("#userProfileImageForm")[0];
console.log(profileImageForm);
// FormData 객체를 이용하면 form 태그의 필드와 그 값을 나타내는 일련의 key/value 쌍을 담을 수 있다.
let formData = new FormData(profileImageForm);
$.ajax({
type: "put",
url: `/api/user/${principalId}/profileImageUrl`,
data: formData,
contentType: false, // 필수 : x-www-form-urlencoded로 파싱되는 것을 방지
processData: false, // 필수: contentType을 false로 줬을 때 QueryString 자동 설정됨. 해제
enctype: "multipart/form-data",
dataType: "json"
}).done(res=>{
// 사진 전송 성공시 이미지 변경
let reader = new FileReader();
reader.onload = (e) => {
$("#userProfileImage").attr("src", e.target.result);
}
reader.readAsDataURL(f); // 이 코드 실행시 reader.onload 실행됨.
}).fail(error=>{
console.log("오류", error);
});
});
}
UserApiController
- 사진데이터도 받기 때문에 MultipartFile도 받는데, html에서의 input 아이디와 똑같은 이름으로 받아야한다.
- userService에 principalId와 파일정보를 넘긴다.
- 회원사진이 변경되면 세션값이 변경되야하기 때문에 변경된 userEntity를 받아서 세션변경을 해준다.
@RequiredArgsConstructor
@RestController
public class UserApiController {
private final UserService userService;
private final FollowService followService;
@PutMapping("/api/user/{principalId}/profileImageUrl")
public ResponseEntity<?> profileImageUrlUpdate(@PathVariable int principalId, MultipartFile profileImageFile,
@AuthenticationPrincipal PrincipalDetails principalDetails){
User userEntity = userService.profileImageUrlUpdate(principalId, profileImageFile);
principalDetails.setUser(userEntity); // 세션 변경
return new ResponseEntity<>(new CMRespDto<>(1, "프로필사진변경 성공", null), HttpStatus.OK);
}
..
}
UserService
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final FollowRepositoy followRepositoy;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Value("${file.path}") //application.properties에서 가져옴
private String uploadFolder;
@Transactional
public User profileImageUrlUpdate(int principalId, MultipartFile profileImageFile){
UUID uuid = UUID.randomUUID(); // uuid
String imageFileName = uuid+"_"+profileImageFile.getOriginalFilename(); // 1.jpg
System.out.println("이미지 파일이름 : "+imageFileName);
Path imageFilePath = Paths.get(uploadFolder+imageFileName);
try {
Files.write(imageFilePath, profileImageFile.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
User userEntity = userRepository.findById(principalId).orElseThrow(()->{
// throw -> return 으로 변경
return new CustomApiException("유저를 찾을 수 없습니다.");
});
userEntity.setProfileImageUrl(imageFileName);
return userEntity;
}
'Study > SpringBoot' 카테고리의 다른 글
[Springboot] AOP처리 - 유효성검사 (0) | 2022.06.03 |
---|---|
[Springboot] 댓글기능 구현 (0) | 2022.06.01 |
[Springboot] 좋아요 기능 추가 - 2 뷰에 렌더링 (0) | 2022.05.29 |
[Springboot] 좋아요 기능 추가 - 1 Model 및 쿼리 작업 (0) | 2022.05.28 |
[Springboot] 전체 게시글 페이지 구성 (0) | 2022.05.27 |