Skip to content

Commit

Permalink
feat: 프로필 이미지 업로드 기능
Browse files Browse the repository at this point in the history
- 사용자 정보 수정 시 사용
  • Loading branch information
SJ70 committed Aug 8, 2024
1 parent f75fb70 commit 29e3b24
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 5 deletions.
32 changes: 32 additions & 0 deletions src/main/java/com/j9/bestmoments/constants/ImageFileTypes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.j9.bestmoments.constants;

import java.util.Arrays;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ImageFileTypes {
JPEG("image/jpeg"),
PNG("image/png"),
GIF("image/gif"),
BMP("image/bmp"),
TIFF("image/tiff"),
WEBP("image/webp"),
SVG("image/svg+xml"),
;

private final String contentType;

public static boolean contains(String contentType) {
System.out.println(contentType);
if (contentType == null) {
return false;
}
String findingContentType = contentType.toLowerCase();
return Arrays.stream(ImageFileTypes.values())
.map(ImageFileTypes::getContentType)
.anyMatch(type -> type.equals(findingContentType));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
import com.j9.bestmoments.util.AuthenticationUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

Expand Down Expand Up @@ -62,9 +63,9 @@ public ResponseEntity<String> restore() {
return ResponseEntity.ok("성공적으로 복구하였습니다.");
}

@PatchMapping("/my-page")
@PatchMapping(path = "/my-page", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "현재 사용자 정보 수정")
public ResponseEntity<MemberFindDto> update(@RequestBody MemberUpdateDto updateDto) {
public ResponseEntity<MemberFindDto> update(@ModelAttribute @Valid MemberUpdateDto updateDto) {
UUID memberId = AuthenticationUtil.getMemberId();
Member member = memberService.findById(memberId);
memberService.update(member, updateDto);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/j9/bestmoments/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ public void setDescription(String description) {
this.description = description;
}

public void setProfileImageUrl(String profileImageUrl) {
this.profileImageUrl = profileImageUrl;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.j9.bestmoments.dto.request;

import com.j9.bestmoments.validator.ImageTypeCheck;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.springframework.web.multipart.MultipartFile;

public record MemberUpdateDto (

@ImageTypeCheck
MultipartFile file,

@NotNull
@NotBlank
@Size(max = 20, message = "이름은 20자 이내로 입력해주세요.")
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/j9/bestmoments/service/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
public class MemberService {

private final MemberRepository memberRepository;
private final StorageService googleCloudStorageService;

public Page<Member> findAll(Pageable pageable) {
return memberRepository.findAll(PageRequest.of(
Expand Down Expand Up @@ -59,6 +60,8 @@ private Member create(OAuthUserInfoDto oAuthUserInfoDto) {
public Member update(Member member, MemberUpdateDto memberUpdateDto) {
member.setName(memberUpdateDto.name());
member.setDescription(memberUpdateDto.description());
String profileImageUrl = googleCloudStorageService.uploadFile(memberUpdateDto.file());
member.setProfileImageUrl(profileImageUrl);
return memberRepository.save(member);
}

Expand Down
17 changes: 17 additions & 0 deletions src/main/java/com/j9/bestmoments/validator/ImageTypeCheck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.j9.bestmoments.validator;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = ImageTypeValidator.class)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ImageTypeCheck {
String message() default "Invalid Image File Type";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
16 changes: 16 additions & 0 deletions src/main/java/com/j9/bestmoments/validator/ImageTypeValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.j9.bestmoments.validator;

import com.j9.bestmoments.constants.ImageFileTypes;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.multipart.MultipartFile;

public class ImageTypeValidator implements ConstraintValidator<ImageTypeCheck, MultipartFile> {

@Override
public boolean isValid(@NotNull MultipartFile file, ConstraintValidatorContext context) {
String contentType = file.getContentType();
return ImageFileTypes.contains(contentType);
}
}

0 comments on commit 29e3b24

Please sign in to comment.