Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Haeseung`s demo #25

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
44fb985
add : ERD 추가
lee-haeseung Jun 25, 2024
2d4b8b7
add : board, post, comment entity 추가
lee-haeseung Jun 26, 2024
ac4466f
modify : id Integer에서 Long type으로 수정
lee-haeseung Jun 26, 2024
9db419d
add : OneToMany 관계 추가
lee-haeseung Jun 26, 2024
6942014
fix : javax, hibernate 수정
lee-haeseung Jun 28, 2024
7a15f44
feature : board controller 추가
lee-haeseung Jun 28, 2024
e0b670a
feature : 게시판 관련 예외 처리
lee-haeseung Jun 28, 2024
982b549
feature : post 관련 기능 추가
lee-haeseung Jun 28, 2024
a0efd18
add : post response에 생성,수정 시간 추가
lee-haeseung Jun 29, 2024
d60fed3
add : entity 별로 @DynamicUpdate, @DynamicInsert 추가
lee-haeseung Jun 29, 2024
506415c
feature : comment 관련 기능 추가
lee-haeseung Jun 29, 2024
fe5824d
feature : post 응답시 그에 해당하는 comment도 함께 반환
lee-haeseung Jun 29, 2024
acf0dcc
feature : comment controller 구현
lee-haeseung Jun 29, 2024
9966c01
feature : post(게시물) 관련 예외 처리
lee-haeseung Jun 29, 2024
406c22a
feature : comment(댓글) 관련 예외 처리
lee-haeseung Jun 29, 2024
e7d103c
fix : board(게시판) 관련 오류 수정
lee-haeseung Jun 29, 2024
5585d82
fix : post 및 comment 오류 수정
lee-haeseung Jun 29, 2024
259fc79
fix : swagger 수정
lee-haeseung Jun 29, 2024
cd83aa8
fix : save 시 자동으로 기본값 들어가게 설정
lee-haeseung Jul 2, 2024
4a12bd5
feat : 댓글 좋아요 관련 기능 추가
lee-haeseung Jul 2, 2024
11d7e87
feat : 댓글 get하면 좋아요 수 반환
lee-haeseung Jul 2, 2024
c14ecea
feature : post(게시물) 좋아요 관련 기능 구현
lee-haeseung Jul 2, 2024
90c87b3
modify : paging 기능을 위해 게시물 리스트 조회 기능 단순하게 수정
lee-haeseung Jul 2, 2024
083ca3d
modify : paging 기능을 위해 게시물 리스트 조회 기능 단순하게 수정
lee-haeseung Jul 2, 2024
d0081f2
feature : paging 처리
lee-haeseung Jul 2, 2024
707ba6a
feature : s3 이용해서 이미지 저장기능 구현
lee-haeseung Jul 3, 2024
600e917
Revert "feature : s3 이용해서 이미지 저장기능 구현"
lee-haeseung Jul 5, 2024
e5b4ec2
fix : post repository 수정
lee-haeseung Jul 5, 2024
7bc39c0
feat : s3연결 기능 구형
lee-haeseung Jul 5, 2024
c869954
fix : 이미지 없이 post 생성 요청하는 경우 오류 해결
lee-haeseung Jul 5, 2024
a085688
modify : (comment) 로그인 정보 바탕으로 유저 정보 가져오게 수정
lee-haeseung Jul 5, 2024
a969495
modify : (comment) 로그인 정보 바탕으로 유저 정보 가져오게 수정
lee-haeseung Jul 5, 2024
4f23cd3
modify : (post) 로그인 정보 바탕으로 유저 정보 가져오게 수정
lee-haeseung Jul 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# UMC Spring A팀 레포지토리입니다.
![alt text](image.png)
Binary file added haeseung/commit-rule.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 25 additions & 26 deletions umc/build.gradle
Original file line number Diff line number Diff line change
@@ -1,53 +1,52 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.11'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'java'
id 'org.springframework.boot' version '3.1.11'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

group = 'com.umc'
version = '0.0.1-SNAPSHOT'

java {
sourceCompatibility = '17'
sourceCompatibility = '17'
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
mavenCentral()
}

dependencies {

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'junit:junit:4.13.1'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
runtimeOnly 'com.mysql:mysql-connector-j'
implementation group: 'org.hibernate', name: 'hibernate-spatial', version: '5.6.15.Final'
// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.15'
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
runtimeOnly 'com.mysql:mysql-connector-j'
// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

}

tasks.named('bootBuildImage') {
builder = 'paketobuildpacks/builder-jammy-base:latest'
builder = 'paketobuildpacks/builder-jammy-base:latest'
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}
48 changes: 48 additions & 0 deletions umc/src/main/java/com/umc/common/config/S3Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.umc.common.config;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import jakarta.annotation.PostConstruct;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Getter
public class S3Config {

private AWSCredentials awsCredentials;

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

@Value("${cloud.aws.credentials.access-key}")
private String accessKey;

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

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

@Value("${cloud.aws.s3.path.post}")
private String postPath;

@PostConstruct
public void init() {
this.awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
}

@Bean
public AmazonS3Client amazonS3Client() {
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
}
5 changes: 1 addition & 4 deletions umc/src/main/java/com/umc/common/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.umc.common.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.umc.common.jwt.JwtAuthenticationFilter;
import com.umc.common.jwt.JwtTokenProvider;
import com.umc.domain.user.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -37,8 +35,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.requestMatchers("/api/users/login").permitAll()
.requestMatchers("/upload").permitAll()
.requestMatchers("/api/**").permitAll()
.requestMatchers("/swagger-ui/**").permitAll()
.requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/", "/api-docs/**", "/api-docs/swagger-config/*", "/swagger-ui/*", "/swagger-ui/**", "/v3/api-docs/**").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
Expand Down
10 changes: 8 additions & 2 deletions umc/src/main/java/com/umc/common/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ForwardedHeaderFilter;

@Configuration
public class SwaggerConfig {

@Bean
ForwardedHeaderFilter forwardedHeaderFilter() {
return new ForwardedHeaderFilter();
}

@Bean
public OpenAPI SchrodingerApi() {
Info info = new Info()
.title("BuddyU API")
.description("BuddyU API 명세서")
.title("제목")
.description("명세서 설명")
.version("1.0.0");

String jwtSchemeName = "JWT TOKEN";
Expand Down
6 changes: 3 additions & 3 deletions umc/src/main/java/com/umc/common/entity/BaseTimeEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@


import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.umc.common.exception.handler;

import com.umc.common.exception.GeneralException;
import com.umc.common.response.BaseErrorCode;

public class BoardHandler extends GeneralException {

public BoardHandler(BaseErrorCode code) {
super(code);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.umc.common.exception.handler;

import com.umc.common.exception.GeneralException;
import com.umc.common.response.status.ErrorCode;

public class CommentHandler extends GeneralException {
public CommentHandler(ErrorCode code) {
super(code);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.umc.common.exception.handler;

import com.umc.common.exception.GeneralException;
import com.umc.common.response.status.ErrorCode;

public class PostHandler extends GeneralException {
public PostHandler(ErrorCode code) {
super(code);
}
}
10 changes: 10 additions & 0 deletions umc/src/main/java/com/umc/common/response/status/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ public enum ErrorCode implements BaseErrorCode {
MEMBER_SIGNUP_ERROR(HttpStatus.BAD_REQUEST, "SIGNUP4001", "회원가입 유효성 검사 실패"),
EMAIL_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "SIGNUP4002", "이미 존재하는 이메일입니다."),

// Board, 게시판 관련 에러
BOARD_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "BOARD4001", "이미 존재하는 게시판입니다."),
BOARD_NOT_EXIST(HttpStatus.BAD_REQUEST, "BOARD4002", "존재하지 않는 게시판입니다."),
BOARD_NOT_AVAILABLE_STATUS(HttpStatus.BAD_REQUEST, "BOARD4003", "존재하지 않는 게시판 상태입니다."),

// Post, 게시물 관련 에러
POST_NOT_EXIST(HttpStatus.BAD_REQUEST, "POST4001", "존재하지 않는 게시물입니다."),

// Comment, 댓글 관련 에러
COMMENT_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMENT4001", "존재하지 않는 댓글입니다."),
;


Expand Down
42 changes: 42 additions & 0 deletions umc/src/main/java/com/umc/common/s3/AmazonS3Manager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.umc.common.s3;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.umc.common.config.S3Config;
import com.umc.domain.post.entity.Uuid;
import com.umc.domain.post.repository.UuidRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@Slf4j
@Component
@RequiredArgsConstructor
public class AmazonS3Manager {

private final AmazonS3 amazonS3;

private final S3Config s3Config;

private final UuidRepository uuidRepository;

public String uploadFild(String keyName, MultipartFile file) {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
try {
amazonS3.putObject(new PutObjectRequest(s3Config.getBucket(), keyName, file.getInputStream(), metadata));
}catch (IOException e){
log.error("error at AmazonS3Manager uploadFile : {}", (Object) e.getStackTrace());
}

return amazonS3.getUrl(s3Config.getBucket(), keyName).toString();
}

public String generatePostName(Uuid uuid) {
return s3Config.getPostPath() + '/' + uuid.getUuid();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.umc.domain.board.controller;

import com.umc.common.response.ApiResponse;
import com.umc.domain.board.dto.BoardCreateRequestDTO;
import com.umc.domain.board.dto.BoardListResponseDTO;
import com.umc.domain.board.dto.BoardResponseDTO;
import com.umc.domain.board.dto.BoardUpdateRequestDTO;
import com.umc.domain.board.service.BoardService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/boards")
public class BoardController {

private final BoardService boardService;

@PostMapping //생성
public ApiResponse<BoardResponseDTO> createBoard(@Valid @RequestBody BoardCreateRequestDTO boardCreateRequestDTO) {
return boardService.createBoard(boardCreateRequestDTO);
}

@DeleteMapping("/{boardId}") // 삭제
public ApiResponse<String> deleteBoard(@Valid @PathVariable Long boardId) {
return boardService.deleteBoard(boardId);
}

@GetMapping // 전체 조회(조건 추가 가능)
public ApiResponse<BoardListResponseDTO> getAllBoardList(
@RequestParam(required = false) String title,
@RequestParam(required = false) String status
) {
return boardService.getBoardList(title, status);
}

@GetMapping("/{boardId}") // 하나 조회
public ApiResponse<BoardResponseDTO> getBoard(@Valid @PathVariable Long boardId) {
return boardService.getBoardById(boardId);
}

@PutMapping("/{boardId}")
public ApiResponse<BoardResponseDTO> updateBoard(
@Valid @PathVariable Long boardId,
@Valid @RequestBody BoardUpdateRequestDTO boardUpdateRequestDTO) {
return boardService.updateBoard(boardId, boardUpdateRequestDTO);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.umc.domain.board.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class BoardCreateRequestDTO {
private String title;
private String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.umc.domain.board.dto;

import com.umc.domain.board.entity.Board;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.stream.Collectors;

@Getter
@Setter
public class BoardListResponseDTO {
private Integer numberOfBoards;
private List<ReducedBoardDTO> boardList;

public BoardListResponseDTO(List<Board> boardList) {
this.boardList = boardList.stream()
.map(board -> new ReducedBoardDTO(board.getId(), board.getTitle()))
.collect(Collectors.toList());
this.numberOfBoards = boardList.size();
}
}
30 changes: 30 additions & 0 deletions umc/src/main/java/com/umc/domain/board/dto/BoardResponseDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.umc.domain.board.dto;

import com.umc.domain.board.entity.Board;
import com.umc.domain.board.entity.BoardStatus;
import com.umc.domain.post.dto.PostListResponseDTO;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;

@Getter
@Setter
@RequiredArgsConstructor
public class BoardResponseDTO {

private Long id;
private String title;
private String description;
private BoardStatus status;
private PostListResponseDTO postList;

public BoardResponseDTO(Board board) {
id = board.getId();
title = board.getTitle();
description = board.getDescription();
status = board.getStatus();
postList = new PostListResponseDTO(board.getPosts() != null ? board.getPosts() : new ArrayList<>());
}
}
Loading