Skip to content

Commit

Permalink
[Merge] 3차 세미나 - 실습과제 (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
sjk4618 authored May 20, 2024
2 parents bfda960 + 180adcd commit cccb8a8
Show file tree
Hide file tree
Showing 23 changed files with 411 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.sopt.springFirstSeminar.common;


import org.sopt.springFirstSeminar.common.dto.ErrorMessage;
import org.sopt.springFirstSeminar.common.dto.SuccessMessage;
import org.springframework.http.ResponseEntity;

public interface ApiResponseUtil {

static ResponseEntity<BaseResponse<?>> success(SuccessMessage successMessage) {
return ResponseEntity
.status(successMessage.getStatus())
.body(BaseResponse.of(successMessage));
}

static <T> ResponseEntity<BaseResponse<?>> success(SuccessMessage successMessage, T data) {
return ResponseEntity
.status((successMessage.getStatus()))
.body(BaseResponse.of(successMessage, data));
}

static ResponseEntity<BaseResponse<?>> fail(ErrorMessage errorMessage) {
return ResponseEntity
.status(errorMessage.getStatus())
.body(BaseResponse.of(errorMessage));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.sopt.springFirstSeminar.common;


import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.sopt.springFirstSeminar.common.dto.ErrorMessage;
import org.sopt.springFirstSeminar.common.dto.SuccessMessage;
import org.sopt.springFirstSeminar.common.dto.SuccessStatusResponse;

@Builder(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class BaseResponse<T> {
private final int status;
private final String message;

@JsonInclude(JsonInclude.Include.NON_NULL)
private final T data;

public static BaseResponse<?> of(SuccessMessage successMessage) {
return builder()
.status(successMessage.getStatus())
.message(successMessage.getMessage())
.build();
}

public static <T> BaseResponse<?> of(SuccessMessage successMessage, T data) {
return builder()
.status(successMessage.getStatus())
.message(successMessage.getMessage())
.data(data)
.build();
}

public static BaseResponse<?> of(ErrorMessage errorMessage) {
return builder()
.status(errorMessage.getStatus())
.message(errorMessage.getMessage())
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
public class GlobalExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage()));
protected ResponseEntity<BaseResponse<?>> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
return ApiResponseUtil.fail(ErrorMessage.MAX_BLOG_CONTENT);
}

@ExceptionHandler(NotFoundException.class)
protected ResponseEntity<ErrorResponse> handleNotFoundException(NotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ErrorResponse.of(ErrorMessage.MEMBER_NOT_FOUND));
protected ResponseEntity<BaseResponse<?>> handleNotFoundException(NotFoundException e) {
return ApiResponseUtil.fail(e.getErrorMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
@AllArgsConstructor
public enum ErrorMessage {
MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "ID에 해당하는 사용자가 존재하지 않습니다."),
BLOG_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "BLOGID에 해당하는 블로그가 존재하지 않습니다.")

BLOG_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "BLOG ID에 해당하는 블로그가 존재하지 않습니다."),
BLOG_NOT_MATCH_MEMBER(HttpStatus.NOT_FOUND.value(), "해당 멤버 ID에 해당하는 블로그ID가 아닙니다."),
CONTENT_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "POST ID에 해당하는 글이 존재하지 않습니다"),
MAX_BLOG_CONTENT(HttpStatus.BAD_REQUEST.value(), "블로그 글이 최대 글자 수(20)를 초과했습니다")
;

private final int status;
private final String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
public enum SuccessMessage {

BLOG_CREATE_SUCCESS(HttpStatus.CREATED.value(), "블로그 생성이 완료되었습니다."),
BLOG_CONTENT_CREATE_SUCCESS(HttpStatus.CREATED.value(), "블로그에 글 작성이 완료되었습니다."),
GET_BLOG_CONTENT_SUCCESS(HttpStatus.OK.value(), "블로그 글 가져오기가 완료되었습니다."),
;
private final int status;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.sopt.springFirstSeminar.common.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AccessLevel;
import lombok.Builder;

@Builder(access = AccessLevel.PRIVATE)
public record SuccessStatusResponse<T>(
int status,
String message,
@JsonInclude(value = JsonInclude.Include.NON_NULL) //이거붙이니까 data없는 곳은 response에 안뜸(공부해야됨)!!
T data
) {

public static SuccessStatusResponse<?> of(SuccessMessage successMessage) {
return builder()
.status(successMessage.getStatus())
.message(successMessage.getMessage())
.build();
}

public static <T> SuccessStatusResponse<?> of(SuccessMessage successMessage, T data) {
return builder()
.status(successMessage.getStatus())
.message(successMessage.getMessage())
.data(data)
.build();
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.springFirstSeminar.common.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateFormatUtil {

private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

public static String format(LocalDateTime dateTime) {
return format(dateTime, DEFAULT_DATE_FORMAT);
}

public static String format(LocalDateTime dateTime, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return dateTime.format(formatter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,4 @@

@EnableJpaAuditing
@Configuration
public class JpaAuditingConfig {



}
public class JpaAuditingConfig { }
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.sopt.springFirstSeminar.common.dto.SuccessMessage;
import org.sopt.springFirstSeminar.common.dto.SuccesttStatusResponse;
import org.sopt.springFirstSeminar.common.dto.SuccessStatusResponse;
import org.sopt.springFirstSeminar.service.BlogService;
import org.sopt.springFirstSeminar.service.dto.BlogCreateRequest;
import org.sopt.springFirstSeminar.service.dto.BlogTitleUpdateRequest;
Expand All @@ -20,19 +20,20 @@ public class BlogController {
private final BlogService blogService;

@PostMapping("/blog")
public ResponseEntity<SuccesttStatusResponse> createBlog(
@RequestHeader(name = "memberId") Long memberId,
@RequestBody BlogCreateRequest blogCreateRequest
public ResponseEntity<SuccessStatusResponse<?>> createBlog(
@RequestHeader(name = "memberId") final Long memberId,
@RequestBody final BlogCreateRequest blogCreateRequest
) {
return ResponseEntity.status(HttpStatus.CREATED)
return ResponseEntity
.status(HttpStatus.CREATED)
.header("Location", blogService.create(memberId, blogCreateRequest))
.body(SuccesttStatusResponse.of(SuccessMessage.BLOG_CREATE_SUCCESS));
.body(SuccessStatusResponse.of(SuccessMessage.BLOG_CREATE_SUCCESS));
}

@PatchMapping("/blog/{blogId}/title")
public ResponseEntity updateBlogTitle(
@PathVariable Long blogId,
@Valid @RequestBody BlogTitleUpdateRequest blogTitleUpdateRequest) {
@PathVariable final Long blogId,
@Valid @RequestBody final BlogTitleUpdateRequest blogTitleUpdateRequest) {
blogService.updateTitle(blogId, blogTitleUpdateRequest);
return ResponseEntity.noContent().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ public class MemberController {
private final MemberService memberService;

@PostMapping
public ResponseEntity createMember(@RequestBody MemberCreateDTO memberCreate) {
public ResponseEntity createMember(@RequestBody final MemberCreateDTO memberCreate) {
return ResponseEntity.created(URI.create(memberService.createMember(memberCreate)))
.build();
}

@GetMapping("/{memberId}")
public ResponseEntity<MemberFindDTO> findMemberById(@PathVariable Long memberId) {
public ResponseEntity<MemberFindDTO> findMemberById(@PathVariable final Long memberId) {
return ResponseEntity.ok(memberService.findMemberById(memberId));
}

@DeleteMapping("/{memberId}")
public ResponseEntity deleteMemberById(@PathVariable Long memberId) {
public ResponseEntity deleteMemberById(@PathVariable final Long memberId) {
memberService.deleteMemberById(memberId);
return ResponseEntity.noContent().build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.sopt.springFirstSeminar.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.sopt.springFirstSeminar.common.ApiResponseUtil;
import org.sopt.springFirstSeminar.common.BaseResponse;
import org.sopt.springFirstSeminar.common.dto.SuccessMessage;
import org.sopt.springFirstSeminar.common.dto.SuccessStatusResponse;
import org.sopt.springFirstSeminar.service.PostService;
import org.sopt.springFirstSeminar.service.dto.BlogAllContentResponseDTO;
import org.sopt.springFirstSeminar.service.dto.BlogContentRequestDTO;
import org.sopt.springFirstSeminar.service.dto.BlogContentResponseDTO;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/v1")
@RequiredArgsConstructor
public class PostController {

private final PostService postService;

@PostMapping("/post/{blogId}")
public ResponseEntity<BaseResponse<?>> postBlogContent(
@RequestHeader(name = "memberId") final Long memberId,
@PathVariable final Long blogId,
@Valid @RequestBody final BlogContentRequestDTO blogContentRequestDTO
) {
postService.postContent(memberId, blogId, blogContentRequestDTO);
return ApiResponseUtil.success(SuccessMessage.BLOG_CONTENT_CREATE_SUCCESS);
}

@GetMapping("/post/{postId}")
public ResponseEntity<BaseResponse<?>> getPostContent(
@PathVariable final Long postId
) {
final BlogContentResponseDTO response = postService.getBlogContent(postId);
return ApiResponseUtil.success(SuccessMessage.GET_BLOG_CONTENT_SUCCESS, response);
}

@GetMapping("/post/blog/{blogId}")
public ResponseEntity<BaseResponse<?>> getAllPostContent(
@PathVariable final Long blogId
) {
final List<BlogAllContentResponseDTO> response = postService.getBlogAllContent(blogId);
return ApiResponseUtil.success(SuccessMessage.GET_BLOG_CONTENT_SUCCESS, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
Expand All @@ -18,5 +20,4 @@ public abstract class BaseTimeEntity {

@LastModifiedDate
private LocalDateTime updatedAt;

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
@Entity
@Getter
@NoArgsConstructor
public class Blog extends BaseTimeEntity{
public class Blog extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@


import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.sopt.springFirstSeminar.service.dto.BlogContentRequestDTO;

import java.time.LocalDateTime;

@Entity
@Getter
Expand All @@ -14,10 +20,23 @@ public class Post extends BaseTimeEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
private Blog blog;

@NotBlank
private String name;

@NotBlank
private String content;

@ManyToOne(fetch = FetchType.LAZY)
private Blog blog;
@Builder
private Post(Blog blog, String name, String content) {
this.blog = blog;
this.name = name;
this.content = content;
}

// public static Post create(Blog blog, BlogContentRequestDTO blogContentRequestDTO) {
// return new Post(blog, blogContentRequestDTO.name(), blogContentRequestDTO.content());
// }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.sopt.springFirstSeminar.exception;

import lombok.Getter;
import org.sopt.springFirstSeminar.common.dto.ErrorMessage;

@Getter
public class BusinessException extends RuntimeException {

private ErrorMessage errorMessage;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.springFirstSeminar.repository;

import org.sopt.springFirstSeminar.domain.Post;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PostRepository extends JpaRepository<Post, Long> {

}
Loading

0 comments on commit cccb8a8

Please sign in to comment.