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

Refactory of PR #13 #14

Merged
merged 40 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e313192
Add: article create
thelight0804 Jul 5, 2023
fe9b97e
Add: find by title in article
thelight0804 Jul 5, 2023
d85b433
Add: like search by title or content in article
thelight0804 Jul 5, 2023
5a563f8
Add: Update article feature in test code
thelight0804 Jul 5, 2023
71c21fb
Add: Delete article feature in test code
thelight0804 Jul 5, 2023
10e249c
Add: Create comment
thelight0804 Jul 8, 2023
67e0277
Add: Read comment
thelight0804 Jul 8, 2023
247011c
Fix: test get comment
thelight0804 Jul 8, 2023
c305540
Add: update comment
thelight0804 Jul 8, 2023
bdc530d
Add: delete comment
thelight0804 Jul 8, 2023
e76bd33
Add save login user in comment
thelight0804 Jul 9, 2023
e33831b
Add save login user in Article
thelight0804 Jul 9, 2023
55fa8a2
Add method article controller and service
thelight0804 Jul 9, 2023
3d14903
Add Principal in article and comment controller method
thelight0804 Jul 10, 2023
ea9c945
Add Swagger annotation
thelight0804 Jul 11, 2023
6630e49
Fix DI to Article controller of UserService
thelight0804 Jul 12, 2023
8a8d54a
Fix sendError() when create Article
thelight0804 Jul 12, 2023
3d08cfe
Add dto in article
thelight0804 Jul 12, 2023
877e468
Fix http 400, 500 error of Article CRUD
thelight0804 Jul 12, 2023
a72394c
Fix add @controller in ArticleController
thelight0804 Jul 12, 2023
5d5be0a
Add comment DTO
thelight0804 Jul 12, 2023
9c66e7c
Add feature of Comment Create and Read
thelight0804 Jul 12, 2023
dd1ba9b
Fix typo postID -> commentID
thelight0804 Jul 12, 2023
48c9199
Add feature of comment update and delete
thelight0804 Jul 12, 2023
d2f4145
Update: apply mapping path as HTTP Method of REST API
thelight0804 Jul 14, 2023
7c153c1
Update: HttpServletRequest Swagger parameter to hidden
thelight0804 Jul 14, 2023
2073414
Update: add @Parameter to @PathVariable
thelight0804 Jul 14, 2023
ac9ac26
Remove Swagger documentation in service
thelight0804 Jul 14, 2023
3b99ccf
Add: get article by title
thelight0804 Jul 14, 2023
6fd13b0
Update: use orElseThrow() instead of if-else
thelight0804 Jul 14, 2023
a8d6e2f
Fix typo: 게시글 id instead of 댓글 id in swagger parameter annotation
thelight0804 Jul 14, 2023
66e9e2c
Remove findByArticleIdx method
thelight0804 Jul 14, 2023
3f9dd47
feat: Add homepage (index.html)
cmsong111 Jul 16, 2023
735a3b1
feat: Configure Spring Security for homepage access
cmsong111 Jul 16, 2023
12108ba
refactor: Refactor ArticleController APIs
cmsong111 Jul 16, 2023
0a096e7
feat: Add ArticleMapper for Entity-DTO conversion
cmsong111 Jul 16, 2023
770b41a
refactor: Refactor Service logic and add test cases
cmsong111 Jul 16, 2023
0f4ae6a
style: Apply code formatting using IntelliJ IDEA
cmsong111 Jul 16, 2023
7404b0f
refactor: Separate comment-related test code from main class
cmsong111 Jul 16, 2023
53fcee5
refactoring: @Mina-1316 recommends
cmsong111 Aug 8, 2023
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
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,9 @@ gradle-app.setting
# Java heap dump
*.hprof

# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,intellij,java,gradle,windows,macos,linux
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,intellij,java,gradle,windows,macos,linux
.idea/modules/blog.test.iml
.idea/modules/blog.main.iml
.idea/modules/blog.iml
.idea/misc.xml
.idea/Blog-API.iml
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/discord.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/jpa-buddy.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 15 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,30 @@ repositories {
}

dependencies {
// Spring Boot
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.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'
compileOnly 'org.projectlombok:lombok'

implementation group: 'org.mapstruct', name: 'mapstruct', version: '1.5.5.Final'
implementation 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
implementation 'org.projectlombok:lombok'

annotationProcessor group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.5.5.Final'
annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0"
annotationProcessor 'org.projectlombok:lombok'

// Database
implementation 'org.mariadb.jdbc:mariadb-java-client:3.1.4'

// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.mariadb.jdbc:mariadb-java-client:3.1.4'
testAnnotationProcessor 'org.projectlombok:lombok'
implementation 'com.h2database:h2:2.1.214' // TODO : testimplementation으로 변경

implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
// JWT
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
Expand Down
41 changes: 41 additions & 0 deletions src/main/generated/com/gdsc/blog/mapper/ArticleMapperImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.gdsc.blog.mapper;

import com.gdsc.blog.article.dto.ArticleDto;
import com.gdsc.blog.article.entity.Article;
import com.gdsc.blog.comment.entity.Comment;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.processing.Generated;
import org.springframework.stereotype.Component;

@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2023-07-17T01:17:13+0900",
comments = "version: 1.5.5.Final, compiler: javac, environment: Java 17.0.7 (Oracle Corporation)"
)
@Component
public class ArticleMapperImpl implements ArticleMapper {

@Override
public ArticleDto toDto(Article article) {
if ( article == null ) {
return null;
}

ArticleDto.ArticleDtoBuilder articleDto = ArticleDto.builder();

articleDto.idx( article.getIdx() );
articleDto.title( article.getTitle() );
articleDto.content( article.getContent() );
List<Comment> list = article.getComments();
if ( list != null ) {
articleDto.comments( new ArrayList<Comment>( list ) );
}

articleDto.username( article.getUser().getUsername() );
articleDto.createdAt( article.getCreateDate().toLocalDateTime() );
articleDto.modifiedAt( article.getModifyDate().toLocalDateTime() );

return articleDto.build();
}
}
8 changes: 3 additions & 5 deletions src/main/java/com/gdsc/blog/BlogApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

@SpringBootApplication
public class BlogApplication {

public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}

public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
}
123 changes: 123 additions & 0 deletions src/main/java/com/gdsc/blog/article/controller/ArticleController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.gdsc.blog.article.controller;

import com.gdsc.blog.article.dto.ArticleCreateDto;
import com.gdsc.blog.article.dto.ArticleDto;
import com.gdsc.blog.article.dto.ArticleUpdateDto;
import com.gdsc.blog.article.service.ArticleService;
import com.gdsc.blog.security.jwt.JwtTokenProvider;
import com.gdsc.blog.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Controller
@RequestMapping("/api/article")
@RestController
@RequiredArgsConstructor
@Tag(name = "게시글 Controller", description = "Article controller API")
@Slf4j
public class ArticleController {

private final ArticleService articleService;
private final UserService userService;
private final JwtTokenProvider jwtTokenProvider;

/**
* 게시글 생성 API
*
* @param articleCreateDto 게시글 생성 DTO
* @return 생성된 게시글
*/
@PostMapping //컨트롤러 메핑
@Operation(summary = "게시글 생성") //swagger 설명
public ArticleDto createArticle(
@Parameter(name = "게시글 생성 DTO") @RequestBody ArticleCreateDto articleCreateDto,
@Parameter(hidden = true) HttpServletRequest req) {

String username = jwtTokenProvider.getUsername(jwtTokenProvider.resolveToken(req));
return articleService.createArticle(articleCreateDto, username);
}

/**
* 최근 게시글 조회 API
*
* @return 게시글 목록
*/
@GetMapping
@Operation(summary = "최근 게시글 조회")
public List<ArticleDto> getUserArticle() {
return articleService.getRecentArticle();
}

/**
* id 로 게시글 조회
*
* @param id 게시글 id
* @param req HTTP 파싱 객체
* @return 게시글
*/
@GetMapping("/{id}")
@Operation(summary = "id로 게시글 조회")
public ArticleDto getArticleById(
@Parameter(description = "게시글 id") @PathVariable("id") Long id) {
return articleService.getArticleById(id);
}

/**
* 제목으로 게시글 조회
*
* @param title 게시글 제목
* @param req HTTP 파싱 객체
* @return 게시글
*/
@GetMapping("/search")
@Operation(summary = "제목으로 게시글 조회")
public List<ArticleDto> getArticleByTitle(
@Parameter(description = "게시글 제목") @RequestParam String title,
@Parameter(hidden = true) HttpServletRequest req) {
return articleService.findArticleByTitle(title);
}

/**
* 게시글 수정
*
* @param id 게시글 id
* @param dto 게시글 수정 정보
* @param req HTTP 파싱 객체
*/
@PatchMapping("/{id}")
@Operation(summary = "게시글 수정")
public ArticleDto updateArticle(
@Parameter(description = "게시글 id") @PathVariable(value = "id") Long id,
@Parameter(name = "게시글 수정 DTO") @RequestBody ArticleUpdateDto dto,
@Parameter(hidden = true) HttpServletRequest req) {

String username = jwtTokenProvider.getUsername(jwtTokenProvider.resolveToken(req));
return articleService.updateArticle(id, dto, username);
}

/**
* 게시글 삭제 API
*
* @param id 게시글 id
* @param req HTTP 파싱 객체
*/
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
@Operation(summary = "게시글 삭제")
public void deleteArticle(
@Parameter(description = "게시글 id") @PathVariable(value = "id") Long id,
@Parameter(hidden = true) HttpServletRequest req) {

String username = jwtTokenProvider.getUsername(jwtTokenProvider.resolveToken(req));
articleService.deleteArticle(id, username);
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/gdsc/blog/article/dto/ArticleCreateDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.gdsc.blog.article.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Setter
public class ArticleCreateDto {
@Schema(description = "제목", example = "게시글 제목")
public String title;

@Schema(description = "내용", example = "게시글 내용")
public String content;
}
23 changes: 23 additions & 0 deletions src/main/java/com/gdsc/blog/article/dto/ArticleDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.gdsc.blog.article.dto;

import com.gdsc.blog.comment.entity.Comment;
import lombok.*;

import java.time.LocalDateTime;
import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Builder
@Getter
@Setter
public class ArticleDto {
private Long idx;
private String title;
private String content;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
private String username;
private List<Comment> comments;
}
17 changes: 17 additions & 0 deletions src/main/java/com/gdsc/blog/article/dto/ArticleUpdateDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.gdsc.blog.article.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Setter
public class ArticleUpdateDto {
@Schema(description = "수정할 제목", example = "수정된 게시글 제목")
public String title;

@Schema(description = "수정할 내용", example = "수정된 게시글 내용")
public String content;
}
Loading