- 좀 더 블로그스러운 느낌을 추가하기 위해 사용자 프로필 이미지를 추가해보았습니다.
- 이를 위해 User 객체에 프로필 이미지 URL을 저장하기 위한 문자열 형식의 변수를 우선 추가해주었습니다.
📝 UserApiController
- 컨트롤러에는 아래와 같은 함수를 추가해주었습니다.
package com.cos.blog.controller.api;
...
@RestController
@RequiredArgsConstructor
public class UserApiController {
private final UserService userService;
...
@PutMapping("/api/user/{user_id}/profileImageUrl")
public ResponseDto<?> profileImageUpdate(@PathVariable Long user_id, MultipartFile profileImageFile, @AuthenticationPrincipal PrincipalDetail principalDetail) {
userService.profileImageUpdate(user_id, profileImageFile);
return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
}
}
📝 UserService
- 다음으로 Service단에도 아래와 같이 함수를 추가해주었습니다.
package com.cos.blog.service;
...
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
...
@Transactional
public void profileImageUpdate(Long user_id, MultipartFile profileImageFile) {
UUID uuid = UUID.randomUUID();
String imageFileName = uuid + "_" + profileImageFile.getOriginalFilename();
Path imageFilePath = Paths.get(uploadFolder + imageFileName);
try {
Files.write(imageFilePath, profileImageFile.getBytes());
} catch(Exception e) {
e.printStackTrace();
}
User user = userRepository.findById(user_id).orElseThrow(() -> {
return new IllegalArgumentException("프로필 이미지 수정 실패: 존재하지 않는 회원입니다.");
});
user.setProfile_image_url(imageFileName);
}
}
📝 application.yml, SecurityConfig
- 다음으로는 사용자 이미지를 외부 폴더에 저장하거나 외부 폴더에 저장되어 있는 사용자 이미지 파일을 불러오기 위해 아래와 같은 설정을 수행해주었습니다.
- 우선 application.yml 파일에 아래와 같이 코드를 추가해주었습니다.
file:
path: D:/workspace/springboot/upload/
- 다음으로 SecurityConfig 클래스에 아래와 같은 코드를 추가해주었습니다.
package com.cos.blog.config;
...
@Configuration //빈등록 (IoC관리)
@EnableWebSecurity //security 필터 등록
@EnableGlobalMethodSecurity(prePostEnabled = true) //특정 주소로 접근하면 권한 및 인증을 미리 체크하겠다는 뜻
@RequiredArgsConstructor
public class SecurityConfig implements WebMvcConfigurer {
...
@Value("${file.path}")
private String uploadFolder;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
WebMvcConfigurer.super.addResourceHandlers(registry);
registry
.addResourceHandler("/upload/**") //jsp 페이지에서 '/upload/**'와 같은 주소 패턴이 요청되면 실행
.addResourceLocations("file:///" + uploadFolder)
.setCachePeriod(60 * 10 * 6) //1시간
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
...
}
📝 user.js
- 사용자 프로필 이미지 변경에 따른 ajax 요청은 아래와 같이 구현하였습니다.
function profileImageUpload(user_id) {
$("#userProfileImageInput").click();
$("#userProfileImageInput").on("change", (e) => {
let f = e.target.files[0];
if (!f.type.match("image.*")) {
alert("이미지를 등록해야 합니다.");
return;
}
// FormData 객체를 이용하면 form 태그의 필드와 그 값을 나타내는 일련의 key/value 쌍을 담을 수 있음
let userProfileImageForm = $("#userProfileImageForm")[0];
let formData = new FormData(userProfileImageForm);
// 서버에 이미지 전송하기
$.ajax({
type: "PUT",
url: `/api/user/${user_id}/profileImageUrl`,
data: formData,
contentType: false, // x-www-form-urlencoded로 파싱되는 것을 방지
processData: false, // contentType을 false로 설정할 경우 QueryString이 자동 설정되는 것을 방지
enctype: "multipart/form-data",
dataType: "json"
}).done(resp => {
// 사진 전송 성공시 이미지 변경
let reader = new FileReader();
reader.onload = (e) => {
$("#userProfileImage").attr("src", e.target.result);
}
reader.readAsDataURL(f); // 이 코드 실행시 reader.onload 실행됨.
}).fail(error => {
console.log(error);
});
});
}
'🚗 Backend Toy Project > 스프링 부트 게시판' 카테고리의 다른 글
[스프링부트 게시판] 35. 관리자 페이지 - 회원 관리 (0) | 2022.10.24 |
---|---|
[스프링부트 게시판] JPA Specification을 통해 쿼리 조건 다루기 (0) | 2022.10.06 |
[스프링부트 게시판] 33. 댓글 알림 기능 (1) | 2022.09.23 |
[스프링부트 게시판] 32. 이전에 봤던 글 표시 (0) | 2022.09.17 |
[스프링부트 게시판] 31. 이전글, 다음글 구현 (0) | 2022.09.06 |