Skip to content

Commit

Permalink
#3 feat : 프로필 이미지 추가, AWS S3 연동, User 출력 수정 (Socket Exception)
Browse files Browse the repository at this point in the history
  • Loading branch information
Suanna01 committed Apr 13, 2023
1 parent 779b0a1 commit 55818ee
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 5 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ dependencies {
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'

// AWS 연동
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
}

tasks.named('test') {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/zatch/zatchserver/ResponseMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class ResponseMessage {
public static final String USER_TOWN_SUCCESS = "회원 동네 설정 성공";
public static final String MY_PROFILE_SUCCESS = "내 프로필 불러오기 성공";
public static final String MYPAGE_SUCCESS = "마이페이지 불러오기 성공";
public static final String PROFILE_IMAGE_UPLOAD_SUCCESS = "프로필 업로드 성공";
public static final String USER_NICKNAME_EDIT_SUCCESS ="회원 닉네임 수정 성공";
public static final String INTERNAL_SERVER_ERROR = "서버 내부 에러";
public static final String DB_ERROR = "데이터베이스 에러";
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/com/zatch/zatchserver/config/S3Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.zatch.zatchserver.config;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class S3Config {
@Value("${cloud.aws.credentials.accessKey}")
private String accessKey;

@Value("${cloud.aws.credentials.secretKey}")
private String secretKey;

@Value("${cloud.aws.region.static}")
private String region;

// @Bean
// @Primary
// public BasicAWSCredentials awsCredentialsProvider(){
// BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
// return basicAWSCredentials;
// }

@Bean
public AmazonS3 amazonS3Client() {
System.out.println("KEY"+secretKey);
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
// AmazonS3 s3Builder = AmazonS3ClientBuilder
// .standard()
// .withRegion(region)
// .withCredentials(new AWSStaticCredentialsProvider(awsCredentialsProvider()))
// .build();
// return s3Builder;

return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region)
.build();
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/zatch/zatchserver/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
Expand Down Expand Up @@ -133,4 +134,16 @@ public ResponseEntity getMypage(@PathVariable("userId") Long userId) {
return new ResponseEntity(DefaultRes.res(StatusCode.INTERNAL_SERVER_ERROR, ResponseMessage.INTERNAL_SERVER_ERROR, "Error Profile"), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@PostMapping("/{userId}/upload_profile")
@ApiOperation(value = "회원 프로필 이미지 업로드", notes = "회원 프로필 이미지 업로드 API")
public ResponseEntity uploadProfile(@PathVariable("userId") Long userId, @RequestParam(value="image") MultipartFile image) {
try {
System.out.println("param_image : "+image);
userService.uploadProfile(userId, image);
return new ResponseEntity(DefaultRes.res(StatusCode.OK, ResponseMessage.PROFILE_IMAGE_UPLOAD_SUCCESS, image), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity(DefaultRes.res(StatusCode.INTERNAL_SERVER_ERROR, ResponseMessage.INTERNAL_SERVER_ERROR, "Error Image Upload"), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
5 changes: 4 additions & 1 deletion src/main/java/com/zatch/zatchserver/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ public class User {
private String email;
private String profileImgUrl;
private String town;
private String imageUrl;

/*---Constructor---*/
public User(String name, String email, String nickname) {
this.name = name;
this.nickname = nickname;
this.email = email;
this.nickname = nickname;
}

/*---Setter---*/
Expand All @@ -26,4 +26,7 @@ public void changeProfileImg(String profileImgUrl) {
public void setTown(String town) {
this.town = town;
}
// public void setImgaeUrl(String imageUrl) {
// this.imageUrl = imageUrl;
// }
}
11 changes: 11 additions & 0 deletions src/main/java/com/zatch/zatchserver/dto/PostUserProfileReqDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.zatch.zatchserver.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.web.multipart.MultipartFile;

@Getter
@AllArgsConstructor
public class PostUserProfileReqDto {
private MultipartFile image;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.zatch.zatchserver.repository;

import com.zatch.zatchserver.domain.User;
import com.zatch.zatchserver.service.S3Uploader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -43,7 +47,7 @@ public String isSignup(String email) {
}
return "login";
} catch (Exception e){
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Email Not Found");
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Login or Signup Error");
}
}

Expand All @@ -63,14 +67,16 @@ public String getUserId(String email) {
@Override
public Long insert(User user) {
try {
System.out.println("user >>> : "+ user.getName());
System.out.println("user name >>> : "+ user.getName());
System.out.println("user nickname >>> : "+ user.getNickname());
System.out.println("user email >>> : "+ user.getEmail());
String sql = "INSERT INTO user(name, nickname, email) VALUES(?, ?, ?)";
Object[] params = {user.getName(), user.getNickname(), user.getEmail()};
jdbcTemplate.update(sql, params);
System.out.println("Signup sql insert");
return user.getId();
} catch (Exception e){
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Email Not Found");
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Info Insert Error");
}
}

Expand All @@ -83,7 +89,7 @@ public Long modifyNickname(Long userId, String newNickname) {
System.out.println("Modify nickname sql update");
return userId;
} catch (Exception e){
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Email Not Found");
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Nickname Modify Error");
}
}

Expand Down Expand Up @@ -152,4 +158,23 @@ public List<Map<String, Object>> getMypage(Long userId) {
}
}

@Autowired
private S3Uploader s3Uploader;

@Override
public String uploadProfile(MultipartFile image, Long userId) {
if(!image.isEmpty()) {
String storedFileName = null;
try {
storedFileName = s3Uploader.upload(image,"images");
System.out.println("filename : "+storedFileName);
jdbcTemplate.update("UPDATE zatch.user SET profile_img_url = ? WHERE user_id = ?", storedFileName, userId);
System.out.println("Profile image upload sql update");
return String.valueOf(image);
} catch (IOException e) {
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Profile Upload Error");
}
}
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "User Profile Empty Error");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.zatch.zatchserver.repository;

import com.zatch.zatchserver.domain.User;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;
Expand All @@ -25,4 +26,6 @@ public interface UserRepository {
String insertToken(Long userId, String token);

List<Map<String, Object>> getMypage(Long userId);

String uploadProfile(MultipartFile image, Long userId);
}
72 changes: 72 additions & 0 deletions src/main/java/com/zatch/zatchserver/service/S3Uploader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.zatch.zatchserver.service;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.PutObjectRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Optional;

@Slf4j
@RequiredArgsConstructor // final 멤버변수가 있으면 생성자 항목에 포함시킴
@Component
@Service
public class S3Uploader {

private final AmazonS3Client amazonS3Client;

@Value("${cloud.aws.s3.bucket}")
private String bucket;

// MultipartFile을 전달받아 File로 전환한 후 S3에 업로드
public String upload(MultipartFile multipartFile, String dirName) throws IOException {
File uploadFile = convert(multipartFile)
.orElseThrow(() -> new IllegalArgumentException("MultipartFile -> File 전환 실패"));
return upload(uploadFile, dirName);
}

private String upload(File uploadFile, String dirName) {
String fileName = dirName + "/" + uploadFile.getName();
String uploadImageUrl = putS3(uploadFile, fileName);

removeNewFile(uploadFile); // 로컬에 생성된 File 삭제 (MultipartFile -> File 전환 하며 로컬에 파일 생성됨)

return uploadImageUrl; // 업로드된 파일의 S3 URL 주소 반환
}

private String putS3(File uploadFile, String fileName) {
amazonS3Client.putObject(
new PutObjectRequest(bucket, fileName, uploadFile)
.withCannedAcl(CannedAccessControlList.PublicRead) // PublicRead 권한으로 업로드 됨
);
return amazonS3Client.getUrl(bucket, fileName).toString();
}

private void removeNewFile(File targetFile) {
if(targetFile.delete()) {
log.info("파일이 삭제되었습니다.");
}else {
log.info("파일이 삭제되지 못했습니다.");
}
}

private Optional<File> convert(MultipartFile file) throws IOException {
File convertFile = new File(file.getOriginalFilename());
if(convertFile.createNewFile()) {
try (FileOutputStream fos = new FileOutputStream(convertFile)) {
fos.write(file.getBytes());
}
return Optional.of(convertFile);
}
return Optional.empty();
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/zatch/zatchserver/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.zatch.zatchserver.service;

import com.zatch.zatchserver.domain.User;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

Expand All @@ -23,4 +24,5 @@ public interface UserService {

String token(Long userId, String token);
String mypage(Long userId);
String uploadProfile(Long userId, MultipartFile image);
}
13 changes: 13 additions & 0 deletions src/main/java/com/zatch/zatchserver/service/UserServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import com.zatch.zatchserver.domain.User;
import com.zatch.zatchserver.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.transaction.Transactional;
import java.io.IOException;
import java.util.List;

@RequiredArgsConstructor
Expand All @@ -13,6 +17,10 @@ public class UserServiceImpl implements UserService {

private final UserRepository userRepository;

// S3
@Autowired
private S3Uploader s3Uploader;

@Override
public String loginOrSignup(String email) {
return userRepository.isSignup(email);
Expand Down Expand Up @@ -62,4 +70,9 @@ public String token(Long userId, String token) {
public String mypage(Long userId) {
return String.valueOf(userRepository.getMypage(userId));
}

@Override
public String uploadProfile(Long userId, MultipartFile image) {
return userRepository.uploadProfile(image, userId);
}
}

0 comments on commit 55818ee

Please sign in to comment.