imgupload, comment 모듈 헥사고날 아키텍쳐로 리아키텍쳐링

This commit is contained in:
jinia91
2022-03-26 22:22:26 +09:00
parent dc233daf71
commit 527edda336
29 changed files with 284 additions and 192 deletions

View File

@@ -5,8 +5,8 @@ import lombok.RequiredArgsConstructor;
import myblog.blog.category.appliacation.port.incomming.CategoryUseCase;
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
import myblog.blog.category.appliacation.port.response.CategorySimpleDto;
import myblog.blog.comment.dto.CommentDtoForLayout;
import myblog.blog.comment.service.CommentService;
import myblog.blog.comment.application.port.incomming.CommentDtoForLayout;
import myblog.blog.comment.application.CommentService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;

View File

@@ -1,7 +1,6 @@
package myblog.blog.category.adapter.imcomming;
import lombok.RequiredArgsConstructor;
import myblog.blog.shared.exception.CustomFormException;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
@@ -31,7 +30,7 @@ public class CategoryListValidator implements Validator {
springValidatorAdapter.validate(object,errors);
}
if (errors.hasErrors()) {
throw new CustomFormException(Objects.requireNonNull(errors.getFieldError()).getDefaultMessage());
throw new InvalidCategoryRequestException(Objects.requireNonNull(errors.getFieldError()).getDefaultMessage());
}
}
}

View File

@@ -0,0 +1,9 @@
package myblog.blog.category.adapter.imcomming;
/*
- REST 컨트롤러 상태 메세지 전송용 커스텀 에러
*/
public class InvalidCategoryRequestException extends RuntimeException {
public InvalidCategoryRequestException(String message) {
super(message);
}
}

View File

@@ -1,35 +1,31 @@
package myblog.blog.comment.controller;
package myblog.blog.comment.adapter.incomming;
import myblog.blog.comment.application.port.incomming.CommentUseCase;
import myblog.blog.comment.application.port.incomming.CommentDto;
import myblog.blog.member.auth.PrincipalDetails;
import myblog.blog.member.doamin.Member;
import lombok.RequiredArgsConstructor;
import myblog.blog.article.application.port.incomming.ArticleQueriesUseCase;
import myblog.blog.article.domain.Article;
import myblog.blog.article.application.ArticleService;
import myblog.blog.comment.dto.CommentDto;
import myblog.blog.comment.dto.CommentForm;
import myblog.blog.comment.service.CommentService;
import myblog.blog.shared.exception.CustomFormException;
import myblog.blog.member.auth.PrincipalDetails;
import myblog.blog.member.doamin.Member;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.Errors;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
import java.util.*;
@RestController
@RequiredArgsConstructor
public class CommentController {
private final CommentService commentService;
private final CommentUseCase commentUseCase;
/*
- 아티클 조회시 아티클에 달린 댓글들 전체 조회
*/
@GetMapping("/comment/list/{articleId}")
public List<CommentDto> getCommentList(@PathVariable Long articleId){
return CommentDto.listCreateFrom(commentService.getCommentList(articleId),0);
return commentUseCase.getCommentList(articleId);
}
/*
@@ -41,19 +37,19 @@ public class CommentController {
@Validated @RequestBody CommentForm commentForm, Errors errors,
@AuthenticationPrincipal PrincipalDetails principal){
if (errors.hasErrors()) {
throw new CustomFormException(Objects.requireNonNull(errors.getFieldError()).getDefaultMessage());
throw new InvalidCommentRequestException(Objects.requireNonNull(errors.getFieldError()).getDefaultMessage());
}
Member member = principal.getMember();
// 부모 댓글인지 자식댓글인지 분기로 저장
if(parentId != null){
commentService.saveCComment(commentForm, member, articleId, parentId);
commentUseCase.saveCComment(commentForm.getContent(), commentForm.isSecret(), member, articleId, parentId);
}
else {
commentService.savePComment(commentForm, member, articleId);
commentUseCase.savePComment(commentForm.getContent(), commentForm.isSecret(), member, articleId);
}
return CommentDto.listCreateFrom(commentService.getCommentList(articleId),0);
return commentUseCase.getCommentList(articleId);
}
/*
@@ -62,7 +58,7 @@ public class CommentController {
@PostMapping("/comment/delete")
public List<CommentDto> deleteComment(@RequestParam Long articleId,
@RequestParam Long commentId) {
commentService.deleteComment(commentId);
return CommentDto.listCreateFrom(commentService.getCommentList(articleId),0);
commentUseCase.deleteComment(commentId);
return commentUseCase.getCommentList(articleId);
}
}

View File

@@ -1,4 +1,4 @@
package myblog.blog.comment.dto;
package myblog.blog.comment.adapter.incomming;
import lombok.Data;

View File

@@ -0,0 +1,9 @@
package myblog.blog.comment.adapter.incomming;
/*
- REST 컨트롤러 상태 메세지 전송용 커스텀 에러
*/
public class InvalidCommentRequestException extends RuntimeException {
public InvalidCommentRequestException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,48 @@
package myblog.blog.comment.adapter.outgoing.persistence;
import lombok.RequiredArgsConstructor;
import myblog.blog.comment.application.port.outgoing.CommentRepositoryPort;
import myblog.blog.article.domain.Article;
import myblog.blog.comment.domain.Comment;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
@RequiredArgsConstructor
public class CommentRepositoryAdapter implements CommentRepositoryPort {
private final JpaCommentRepository jpaCommentRepository;
private final MybatisCommentRepository mybatisCommentRepository;
@Override
public int countCommentsByArticleAndTier(Article article, int tier) {
return jpaCommentRepository.countCommentsByArticleAndTier(article, tier);
}
@Override
public void save(Comment comment) {
jpaCommentRepository.save(comment);
}
@Override
public List<Comment> findCommentsByArticleId(Long articleId) {
return jpaCommentRepository.findCommentsByArticleId(articleId);
}
@Override
public void deleteComment(Long commentId) {
mybatisCommentRepository.deleteComment(commentId);
}
@Override
public List<Comment> findTop5ByOrderByIdDesc() {
return jpaCommentRepository.findTop5ByOrderByIdDesc();
}
@Override
public Optional<Comment> findById(Long parentId) {
return jpaCommentRepository.findById(parentId);
}
}

View File

@@ -1,4 +1,4 @@
package myblog.blog.comment.repository;
package myblog.blog.comment.adapter.outgoing.persistence;
import myblog.blog.article.domain.Article;
import myblog.blog.comment.domain.Comment;
@@ -8,7 +8,7 @@ import org.springframework.data.repository.query.Param;
import java.util.List;
public interface CommentRepository extends JpaRepository<Comment, Long> {
public interface JpaCommentRepository extends JpaRepository<Comment, Long> {
/*
- 특정 아티클에 해당하는 댓글 리스트 가져오기

View File

@@ -1,10 +1,10 @@
package myblog.blog.comment.repository;
package myblog.blog.comment.adapter.outgoing.persistence;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface NaCommentRepository {
public interface MybatisCommentRepository {
/*
- cascade 삭제처리

View File

@@ -1,57 +1,57 @@
package myblog.blog.comment.service;
package myblog.blog.comment.application;
import myblog.blog.article.application.port.incomming.ArticleUseCase;
import myblog.blog.comment.application.port.incomming.CommentUseCase;
import myblog.blog.comment.application.port.incomming.CommentDto;
import myblog.blog.comment.application.port.incomming.CommentDtoForLayout;
import myblog.blog.comment.application.port.outgoing.CommentRepositoryPort;
import myblog.blog.comment.domain.Comment;
import myblog.blog.article.domain.Article;
import myblog.blog.member.doamin.Member;
import lombok.RequiredArgsConstructor;
import myblog.blog.article.application.port.incomming.ArticleUseCase;
import myblog.blog.article.domain.Article;
import myblog.blog.comment.domain.Comment;
import myblog.blog.comment.dto.CommentDtoForLayout;
import myblog.blog.comment.dto.CommentForm;
import myblog.blog.comment.repository.CommentRepository;
import myblog.blog.comment.repository.NaCommentRepository;
import myblog.blog.member.doamin.Member;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Transactional
@RequiredArgsConstructor
public class CommentService {
public class CommentService implements CommentUseCase {
private final ArticleUseCase articleUseCase;
private final CommentRepository commentRepository;
private final NaCommentRepository naCommentRepository;
private final CommentRepositoryPort commentRepositoryPort;
/*
- 아티클에 달린 댓글 전체 가져오기
*/
public List<Comment> getCommentList(Long articleId){
return commentRepository.findCommentsByArticleId(articleId);
@Override
public List<CommentDto> getCommentList(Long articleId){
return CommentDto.listCreateFrom(commentRepositoryPort.findCommentsByArticleId(articleId),0);
}
/*
- 부모 댓글 저장
*/
@CacheEvict(value = "layoutRecentCommentCaching", allEntries = true)
public void savePComment(CommentForm commentForm, Member member, Long articleId){
@Override
public void savePComment(String content, boolean secret, Member member, Long articleId){
Article article = articleUseCase.getArticle(articleId);
Comment comment = Comment.builder()
.article(article)
.content(removeDuplicatedEnter(commentForm))
.content(removeDuplicatedEnter(content))
.tier(0)
.pOrder(commentRepository.countCommentsByArticleAndTier(article,0)+1)
.pOrder(commentRepositoryPort.countCommentsByArticleAndTier(article,0)+1)
.member(member)
.secret(commentForm.isSecret())
.secret(secret)
.build();
commentRepository.save(comment);
commentRepositoryPort.save(comment);
}
@@ -59,22 +59,24 @@ public class CommentService {
- 자식 댓글 저장
*/
@CacheEvict(value = "layoutRecentCommentCaching", allEntries = true)
public void saveCComment(CommentForm commentForm, Member member, Long articleId, Long parentId) {
@Override
public void saveCComment(String content, boolean secret, Member member, Long articleId, Long parentId) {
Article article = articleUseCase.getArticle(articleId);
Comment pComment = commentRepository.findById(parentId).get();
Comment pComment = commentRepositoryPort.findById(parentId)
.orElseThrow(() -> new IllegalArgumentException("NotfoundParentCommentException"));
Comment comment = Comment.builder()
.article(article)
.content(removeDuplicatedEnter(commentForm))
.content(removeDuplicatedEnter(content))
.tier(1)
.pOrder(pComment.getPOrder())
.member(member)
.parents(pComment)
.secret(commentForm.isSecret())
.secret(secret)
.build();
commentRepository.save(comment);
commentRepositoryPort.save(comment);
}
@@ -82,8 +84,9 @@ public class CommentService {
- 댓글 삭제
*/
@CacheEvict(value = "layoutRecentCommentCaching", allEntries = true)
@Override
public void deleteComment(Long commentId){
naCommentRepository.deleteComment(commentId);
commentRepositoryPort.deleteComment(commentId);
}
/*
@@ -93,8 +96,9 @@ public class CommentService {
DTO 매핑 로직 서비스단에서 처리
*/
@Cacheable(value = "layoutRecentCommentCaching", key = "0")
@Override
public List<CommentDtoForLayout> recentCommentList(){
return commentRepository.findTop5ByOrderByIdDesc()
return commentRepositoryPort.findTop5ByOrderByIdDesc()
.stream()
.map(comment ->
new CommentDtoForLayout(comment.getId(), comment.getArticle().getId(), comment.getContent(), comment.isSecret()))
@@ -104,15 +108,15 @@ public class CommentService {
/*
- 중복 개행 개행 하나로 압축 알고리즘
*/
private String removeDuplicatedEnter(CommentForm commentForm) {
private String removeDuplicatedEnter(String content) {
char[] contentBox = new char[commentForm.getContent().length()];
char[] contentBox = new char[content.length()];
int idx = 0;
String zipWord = "\n\n";
for(int i = 0; i< commentForm.getContent().length(); i++){
for(int i = 0; i< content.length(); i++){
contentBox[idx] = commentForm.getContent().charAt(i);
contentBox[idx] = content.charAt(i);
if(contentBox[idx] == '\n'&&idx >= 1){

View File

@@ -1,13 +1,11 @@
package myblog.blog.comment.dto;
package myblog.blog.comment.application.port.incomming;
import lombok.Getter;
import lombok.Setter;
import myblog.blog.comment.domain.Comment;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.*;
/*

View File

@@ -1,4 +1,4 @@
package myblog.blog.comment.dto;
package myblog.blog.comment.application.port.incomming;
import lombok.Getter;
import lombok.Setter;

View File

@@ -0,0 +1,13 @@
package myblog.blog.comment.application.port.incomming;
import myblog.blog.member.doamin.Member;
import java.util.List;
public interface CommentUseCase {
List<CommentDto> getCommentList(Long articleId);
void savePComment(String content, boolean secret, Member member, Long articleId);
void saveCComment(String content, boolean secret, Member member, Long articleId, Long parentId);
void deleteComment(Long commentId);
List<CommentDtoForLayout> recentCommentList();
}

View File

@@ -0,0 +1,16 @@
package myblog.blog.comment.application.port.outgoing;
import myblog.blog.article.domain.Article;
import myblog.blog.comment.domain.Comment;
import java.util.List;
import java.util.Optional;
public interface CommentRepositoryPort {
int countCommentsByArticleAndTier(Article article, int tier);
void save(Comment comment);
List<Comment> findCommentsByArticleId(Long articleId);
void deleteComment(Long commentId);
List<Comment> findTop5ByOrderByIdDesc();
Optional<Comment> findById(Long parentId);
}

View File

@@ -0,0 +1,20 @@
package myblog.blog.imgupload.adapter.incomming;
import myblog.blog.imgupload.service.port.incomming.ImgUploadUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@RestController
@RequiredArgsConstructor
public class UploadImgController {
private final ImgUploadUseCase imgUploadUseCase;
@PostMapping("/article/uploadImg")
public @ResponseBody
String imgUpload(@ModelAttribute UploadImgForm uploadImgForm) throws IOException {
return imgUploadUseCase.storeImg(uploadImgForm.getImg());
}
}

View File

@@ -1,14 +1,11 @@
package myblog.blog.imgupload.dto;
package myblog.blog.imgupload.adapter.incomming;
import lombok.Getter;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;
/*
- 멀티파트 파일 래핑용 DTO
*/
@Getter
@Setter
public class UploadImgDto {
public class UploadImgForm {
private MultipartFile img;
}

View File

@@ -1,8 +1,10 @@
package myblog.blog.imgupload.service;
package myblog.blog.imgupload.adapter.outgoing;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.*;
import lombok.RequiredArgsConstructor;
import myblog.blog.imgupload.domain.ImageFile;
import myblog.blog.imgupload.service.port.outgoing.ImgUploadStrategyPort;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -15,22 +17,22 @@ import java.io.InputStream;
*/
@RequiredArgsConstructor
@Service
public class AwsS3ImgUploadStrategy implements ImgUploadStrategy {
public class AwsS3ImgUploadStrategyAdapter implements ImgUploadStrategyPort {
private final AmazonS3 amazonS3;
@Value("${cloud.aws.s3.bucket}")
private String bucket;
@Override
public String uploadFile(MultipartFile file, String storeFileName) {
public String uploadFile(ImageFile imageFile) {
MultipartFile file = imageFile.getMultipartFile();
ObjectMetadata metadata = createObjectMetadata(file);
try(InputStream inputStream = file.getInputStream()) {
amazonS3.putObject(new PutObjectRequest(bucket, storeFileName, inputStream, metadata)
amazonS3.putObject(new PutObjectRequest(bucket, imageFile.getStoredFileName(), inputStream, metadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (IOException e) {
throw new IllegalArgumentException("파일 업로드에 실패했습니다.");
}
return amazonS3.getUrl(bucket, storeFileName).toString();
return amazonS3.getUrl(bucket, imageFile.getStoredFileName()).toString();
}
/**

View File

@@ -1,11 +1,9 @@
package myblog.blog.imgupload.service;
package myblog.blog.imgupload.adapter.outgoing;
import lombok.RequiredArgsConstructor;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@@ -15,7 +13,8 @@ import java.io.IOException;
*/
//@RequiredArgsConstructor
//@Service
public class GithubRepoImgUploadStrategy implements ImgUploadStrategy {
@Deprecated
public class GithubRepoImgUploadStrategyAdapter {
/*
- 설정 파일로 잡아놓은 깃헙 이미지 레포지토리와 토큰
@@ -34,7 +33,6 @@ public class GithubRepoImgUploadStrategy implements ImgUploadStrategy {
1. 깃허브 Repo에 이미지 업로드
2. 업로드된 Url 반환
*/
@Override
public String uploadFile(MultipartFile multipartFile, String storeFileName) throws IOException {
GitHub gitHub = new GitHubBuilder().withOAuthToken(gitToken).build();
GHRepository repository = gitHub.getRepository(gitRepo);

View File

@@ -1,27 +0,0 @@
package myblog.blog.imgupload.controller;
import lombok.RequiredArgsConstructor;
import myblog.blog.imgupload.dto.UploadImgDto;
import myblog.blog.imgupload.service.ImgUploadServiceImpl;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
@RequiredArgsConstructor
public class UploadImgController {
private final ImgUploadServiceImpl imgUploadServiceImpl;
/*
- 썸네일 업로드 요청
*/
@PostMapping("/article/uploadImg")
public @ResponseBody
String imgUpload(@ModelAttribute UploadImgDto uploadImgDto) throws IOException {
return imgUploadServiceImpl.storeImg(uploadImgDto.getImg());
}
}

View File

@@ -0,0 +1,38 @@
package myblog.blog.imgupload.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.web.multipart.MultipartFile;
import java.util.UUID;
@Getter
@AllArgsConstructor
public class ImageFile {
String originalFileName;
String storedFileName;
MultipartFile multipartFile;
static public ImageFile from(MultipartFile multipartFile){
return new ImageFile(multipartFile.getOriginalFilename(),
createStoreFileName(multipartFile.getOriginalFilename()),
multipartFile
);
}
/*
- 이미지 중복 방지용 무작위 파일 이름 생성기
*/
private static String createStoreFileName(String originalFilename) {
String ext = extractExt(originalFilename);
String uuid = UUID.randomUUID().toString();
return uuid + "." + ext;
}
/*
- 파일 이름 추출
*/
private static String extractExt(String originalFilename) {
int pos = originalFilename.lastIndexOf(".");
return originalFilename.substring(pos + 1);
}
}

View File

@@ -1,9 +1,33 @@
package myblog.blog.imgupload.service;
import lombok.RequiredArgsConstructor;
import myblog.blog.imgupload.domain.ImageFile;
import myblog.blog.imgupload.service.port.incomming.ImgUploadUseCase;
import myblog.blog.imgupload.service.port.outgoing.ImgUploadStrategyPort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.io.IOException;
import java.util.UUID;
public interface ImgUploadService {
List<String> storeFile(List<MultipartFile> imgList);
}
@Service
@Transactional
@RequiredArgsConstructor
public class ImgUploadService implements ImgUploadUseCase {
private final ImgUploadStrategyPort imgUploadStrategyPort;
@Override
public String storeImg(MultipartFile multipartFile) {
validateFile(multipartFile);
ImageFile imageFile = ImageFile.from(multipartFile);
return imgUploadStrategyPort.uploadFile(imageFile);
}
private void validateFile(MultipartFile multipartFile) {
if (multipartFile.isEmpty()) {
throw new IllegalArgumentException("이미지가 존재하지 않습니다.");
}
}
}

View File

@@ -1,51 +0,0 @@
package myblog.blog.imgupload.service;
import lombok.RequiredArgsConstructor;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;
@Service
@Transactional
@RequiredArgsConstructor
public class ImgUploadServiceImpl {
private final ImgUploadStrategy imgUploadStrategy;
public String storeImg(MultipartFile multipartFile) throws IOException {
validateFile(multipartFile);
String storeFileName = createStoreFileName(multipartFile.getOriginalFilename());
return imgUploadStrategy.uploadFile(multipartFile, storeFileName);
}
private void validateFile(MultipartFile multipartFile) {
if (multipartFile.isEmpty()) {
throw new IllegalArgumentException("이미지가 존재하지 않습니다.");
}
}
/*
- 이미지 중복 방지용 무작위 파일 이름 생성기
*/
private String createStoreFileName(String originalFilename) {
String ext = extractExt(originalFilename);
String uuid = UUID.randomUUID().toString();
return uuid + "." + ext;
}
/*
- 파일 이름 추출
*/
private String extractExt(String originalFilename) {
int pos = originalFilename.lastIndexOf(".");
return originalFilename.substring(pos + 1);
}
}

View File

@@ -1,12 +0,0 @@
package myblog.blog.imgupload.service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* 파일 업로드 전략패턴 추상화 인터페이스
*/
public interface ImgUploadStrategy {
String uploadFile(MultipartFile file, String storeFileName) throws IOException;
}

View File

@@ -0,0 +1,9 @@
package myblog.blog.imgupload.service.port.incomming;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
public interface ImgUploadUseCase {
String storeImg(MultipartFile img);
}

View File

@@ -0,0 +1,10 @@
package myblog.blog.imgupload.service.port.outgoing;
import myblog.blog.imgupload.domain.ImageFile;
/**
* 파일 업로드 전략패턴 추상화 인터페이스
*/
public interface ImgUploadStrategyPort {
String uploadFile(ImageFile imageFile);
}

View File

@@ -3,8 +3,8 @@ package myblog.blog.member.controller;
import lombok.RequiredArgsConstructor;
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
import myblog.blog.category.appliacation.CategoryService;
import myblog.blog.comment.dto.CommentDtoForLayout;
import myblog.blog.comment.service.CommentService;
import myblog.blog.comment.application.port.incomming.CommentDtoForLayout;
import myblog.blog.comment.application.CommentService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

View File

@@ -1,9 +0,0 @@
package myblog.blog.shared.exception;
/*
- REST 컨트롤러 상태 메세지 전송용 커스텀 에러
*/
public class CustomFormException extends RuntimeException {
public CustomFormException(String message) {
super(message);
}
}

View File

@@ -1,5 +1,6 @@
package myblog.blog.shared.exception;
import myblog.blog.comment.adapter.incomming.InvalidCommentRequestException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@@ -10,7 +11,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
*/
@RestControllerAdvice
public class ExceptionRestControllerAdvice {
@ExceptionHandler(CustomFormException.class)
@ExceptionHandler(InvalidCommentRequestException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleCategoryControllerException(RuntimeException e) {
return e.getMessage();

View File

@@ -3,8 +3,8 @@ package myblog.blog.shared.queries;
import lombok.RequiredArgsConstructor;
import myblog.blog.category.appliacation.port.incomming.CategoryUseCase;
import myblog.blog.category.appliacation.port.response.CategoryViewForLayout;
import myblog.blog.comment.dto.CommentDtoForLayout;
import myblog.blog.comment.service.CommentService;
import myblog.blog.comment.application.port.incomming.CommentDtoForLayout;
import myblog.blog.comment.application.CommentService;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;