Skip to content

Commit

Permalink
v1.2.0 (#650)
Browse files Browse the repository at this point in the history
v1.2.0
  • Loading branch information
Leejin-Yang authored Sep 15, 2023
2 parents 5a8c1f8 + 14558cb commit 8a8e042
Show file tree
Hide file tree
Showing 101 changed files with 1,321 additions and 572 deletions.
6 changes: 3 additions & 3 deletions backend/src/main/java/com/funeat/FuneatApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
@SpringBootApplication
public class FuneatApplication {

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ public interface AuthController {
description = "기존 회원이면 홈으로 이동, 신규 회원이면 마이페이지로 이동."
)
@GetMapping
ResponseEntity<Void> loginAuthorizeUser(@RequestParam("code") String code, HttpServletRequest request);
ResponseEntity<Void> loginAuthorizeUser(@RequestParam("code") final String code, final HttpServletRequest request);

@Operation(summary = "로그아웃", description = "로그아웃을 한다")
@ApiResponse(
responseCode = "302",
description = "로그아웃 성공."
)
@PostMapping
ResponseEntity<Void> logout(@AuthenticationPrincipal LoginInfo loginInfo, HttpServletRequest request,
HttpServletResponse response);
ResponseEntity<Void> logout(@AuthenticationPrincipal final LoginInfo loginInfo, final HttpServletRequest request,
final HttpServletResponse response);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ public class KakaoPlatformUserProvider implements PlatformUserProvider {

private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;
private final String kakaoRestApiKey;
private final String redirectUri;
private final String kakaoAdminKey;

@Value("${kakao.rest-api-key}")
private String kakaoRestApiKey;

@Value("${kakao.redirect-uri}")
private String redirectUri;

@Value("${kakao.admin-key}")
private String kakaoAdminKey;

public KakaoPlatformUserProvider(final RestTemplateBuilder restTemplateBuilder,
final ObjectMapper objectMapper,
@Value("${kakao.rest-api-key}") final String kakaoRestApiKey,
@Value("${kakao.redirect-uri}") final String redirectUri,
@Value("${kakao.admin-key}") final String kakaoAdminKey) {
final ObjectMapper objectMapper) {
this.restTemplate = restTemplateBuilder.build();
this.objectMapper = objectMapper;
this.kakaoRestApiKey = kakaoRestApiKey;
this.redirectUri = redirectUri;
this.kakaoAdminKey = kakaoAdminKey;
}

@Override
Expand Down Expand Up @@ -118,10 +118,10 @@ private KakaoUserInfoDto convertJsonToKakaoUserDto(final String responseBody) {

@Override
public String getRedirectURI() {
final StringJoiner joiner = new StringJoiner("&");
joiner.add("response_type=code");
joiner.add("client_id=" + kakaoRestApiKey);
joiner.add("redirect_uri=" + redirectUri);
final StringJoiner joiner = new StringJoiner("&")
.add("response_type=code")
.add("client_id=" + kakaoRestApiKey)
.add("redirect_uri=" + redirectUri);

return AUTHORIZATION_BASE_URL + OAUTH_URI + "?" + joiner;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
public class CustomPageableHandlerMethodArgumentResolver extends PageableHandlerMethodArgumentResolver {

@Override
public Pageable resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
public Pageable resolveArgument(final MethodParameter methodParameter, final ModelAndViewContainer mavContainer,
final NativeWebRequest webRequest, final WebDataBinderFactory binderFactory) {
final Pageable pageable = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);

final Sort lastPrioritySort = Sort.by("id").descending();
Expand Down
2 changes: 1 addition & 1 deletion backend/src/main/java/com/funeat/common/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void addFormatters(final FormatterRegistry registry) {
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(customPageableHandlerMethodArgumentResolver);
resolvers.add(authArgumentResolver);
}
Expand Down
11 changes: 11 additions & 0 deletions backend/src/main/java/com/funeat/common/logging/Logging.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.funeat.common.logging;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Logging {
}
91 changes: 91 additions & 0 deletions backend/src/main/java/com/funeat/common/logging/LoggingAspect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.funeat.common.logging;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class LoggingAspect {

private static final List<String> excludeNames = Arrays.asList("image", "images", "request");

private final ObjectMapper objectMapper = new ObjectMapper();
private final Logger log = LoggerFactory.getLogger(this.getClass());

@Pointcut("execution(public * com.funeat.*.presentation.*.*(..))")
private void allPresentation() {
}

@Pointcut("@annotation(com.funeat.common.logging.Logging)")
private void logging() {
}

@Before("allPresentation() && logging()")
public void requestLogging(final JoinPoint joinPoint) {
final HttpServletRequest request = getRequest();
final Map<String, Object> args = getSpecificParameters(joinPoint);

printRequestLog(request, args);
}

private HttpServletRequest getRequest() {
final ServletRequestAttributes servletRequestAttributes
= (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
return servletRequestAttributes.getRequest();
}

private Map<String, Object> getSpecificParameters(final JoinPoint joinPoint) {
final CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature();
final String[] parameterNames = codeSignature.getParameterNames();
final Object[] args = joinPoint.getArgs();

final Map<String, Object> params = new HashMap<>();
for (int i = 0; i < parameterNames.length; i++) {
if (!excludeNames.contains(parameterNames[i])) {
params.put(parameterNames[i], args[i]);
}
}

return params;
}

private void printRequestLog(final HttpServletRequest request, final Object value) {
try {
log.info("[REQUEST {}] [PATH {}] {}",
request.getMethod(), request.getRequestURI(), objectMapper.writeValueAsString(value));
} catch (final JsonProcessingException e) {
log.warn("[LOGGING ERROR] Request 로깅에 실패했습니다");
}
}

@AfterReturning(value = "allPresentation() && logging()", returning = "responseEntity")
public void requestLogging(final ResponseEntity<?> responseEntity) {
printResponseLog(responseEntity);
}

private void printResponseLog(final ResponseEntity<?> responseEntity) {
try {
final String responseStatus = responseEntity.getStatusCode().toString();
log.info("[RESPONSE {}] {}", responseStatus, objectMapper.writeValueAsString(responseEntity.getBody()));
} catch (final JsonProcessingException e) {
log.warn("[LOGGING ERROR] Response 로깅에 실패했습니다");
}
}
}
6 changes: 3 additions & 3 deletions backend/src/main/java/com/funeat/common/s3/S3Uploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.funeat.common.exception.CommonException.NotAllowedFileExtensionException;
import com.funeat.common.exception.CommonException.S3UploadFailException;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
Expand All @@ -20,8 +21,7 @@
@Profile("!test")
public class S3Uploader implements ImageUploader {

public static final String JPEG = "image/jpeg";
public static final String PNG = "image/png";
private static final List<String> INCLUDE_EXTENSIONS = List.of("image/jpeg", "image/png");

@Value("${cloud.aws.s3.bucket}")
private String bucket;
Expand Down Expand Up @@ -55,7 +55,7 @@ public String upload(final MultipartFile image) {

private void validateExtension(final MultipartFile image) {
final String contentType = image.getContentType();
if (!contentType.equals(JPEG) && !contentType.equals(PNG)) {
if (!INCLUDE_EXTENSIONS.contains(contentType)){
throw new NotAllowedFileExtensionException(IMAGE_EXTENSION_ERROR_CODE, contentType);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
@RestControllerAdvice
public class GlobalControllerAdvice {

private static final String ERROR_MESSAGE_DELIMITER = ", ";
private static final String RESPONSE_DELIMITER = ". ";

private final Logger log = LoggerFactory.getLogger(this.getClass());
private final ObjectMapper objectMapper;

Expand All @@ -50,9 +53,9 @@ public ResponseEntity<?> handleParamValidationException(final MethodArgumentNotV
.getAllErrors()
.stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(", "));
.collect(Collectors.joining(ERROR_MESSAGE_DELIMITER));

final String responseErrorMessage = errorMessage + ". " + REQUEST_VALID_ERROR_CODE.getMessage();
final String responseErrorMessage = errorMessage + RESPONSE_DELIMITER + REQUEST_VALID_ERROR_CODE.getMessage();

final ErrorCode<?> errorCode = new ErrorCode<>(REQUEST_VALID_ERROR_CODE.getCode(), responseErrorMessage);

Expand All @@ -66,7 +69,7 @@ private static String getMethodArgumentExceptionLogMessage(final MethodArgumentN
.getFieldErrors()
.stream()
.map(FieldError::getField)
.collect(Collectors.joining(", "));
.collect(Collectors.joining(ERROR_MESSAGE_DELIMITER));

return filedErrorMessages + " 요청 실패";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.funeat.member.dto;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.funeat.product.domain.Product;
import com.funeat.recipe.domain.Recipe;
import com.funeat.recipe.domain.RecipeImage;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

public class MemberRecipeDto {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public class MemberReviewDto {
private final Long favoriteCount;

private MemberReviewDto(final Long reviewId, final Long productId, final String categoryType,
final String productName, final String content,
final Long rating, final Long favoriteCount) {
final String productName, final String content,
final Long rating, final Long favoriteCount) {
this.reviewId = reviewId;
this.productId = productId;
this.categoryType = categoryType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.funeat.auth.dto.LoginInfo;
import com.funeat.auth.util.AuthenticationPrincipal;
import com.funeat.common.logging.Logging;
import com.funeat.member.application.MemberService;
import com.funeat.member.dto.MemberProfileResponse;
import com.funeat.member.dto.MemberRecipesResponse;
Expand Down Expand Up @@ -38,20 +39,17 @@ public MemberApiController(final MemberService memberService, final ReviewServic

@GetMapping
public ResponseEntity<MemberProfileResponse> getMemberProfile(@AuthenticationPrincipal final LoginInfo loginInfo) {
final Long memberId = loginInfo.getId();

final MemberProfileResponse response = memberService.getMemberProfile(memberId);
final MemberProfileResponse response = memberService.getMemberProfile(loginInfo.getId());

return ResponseEntity.ok(response);
}

@Logging
@PutMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Void> putMemberProfile(@AuthenticationPrincipal final LoginInfo loginInfo,
@RequestPart(required = false) final MultipartFile image,
@RequestPart @Valid final MemberRequest memberRequest) {
final Long memberId = loginInfo.getId();

memberService.modify(memberId, image, memberRequest);
memberService.modify(loginInfo.getId(), image, memberRequest);

return ResponseEntity.ok().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface MemberController {
description = "사용자 정보 조회 성공."
)
@GetMapping
ResponseEntity<MemberProfileResponse> getMemberProfile(@AuthenticationPrincipal LoginInfo loginInfo);
ResponseEntity<MemberProfileResponse> getMemberProfile(@AuthenticationPrincipal final LoginInfo loginInfo);

@Operation(summary = "사용자 정보 수정", description = "사용자 닉네임과 프로필 사진을 수정한다.")
@ApiResponse(
Expand All @@ -44,15 +44,15 @@ public ResponseEntity<Void> putMemberProfile(@AuthenticationPrincipal final Logi
description = "사용자 리뷰 조회 성공."
)
@GetMapping
ResponseEntity<MemberReviewsResponse> getMemberReview(@AuthenticationPrincipal LoginInfo loginInfo,
@PageableDefault Pageable pageable);
ResponseEntity<MemberReviewsResponse> getMemberReview(@AuthenticationPrincipal final LoginInfo loginInfo,
@PageableDefault final Pageable pageable);

@Operation(summary = "사용자 꿀조합 조회", description = "사용자가 작성한 꿀조합을 조회한다.")
@ApiResponse(
responseCode = "200",
description = "사용자 꿀조합 조회 성공."
)
@GetMapping
ResponseEntity<MemberRecipesResponse> getMemberRecipe(@AuthenticationPrincipal LoginInfo loginInfo,
@PageableDefault Pageable pageable);
ResponseEntity<MemberRecipesResponse> getMemberRecipe(@AuthenticationPrincipal final LoginInfo loginInfo,
@PageableDefault final Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.funeat.tag.domain.Tag;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand All @@ -46,6 +47,7 @@ public class ProductService {
private static final int THREE = 3;
private static final int TOP = 0;
public static final String REVIEW_COUNT = "reviewCount";
private static final int RANKING_SIZE = 3;

private final CategoryRepository categoryRepository;
private final ProductRepository productRepository;
Expand Down Expand Up @@ -82,7 +84,7 @@ public ProductsInCategoryResponse getAllProductsInCategory(final Long categoryId
}

private Page<ProductInCategoryDto> getAllProductsInCategory(final Pageable pageable, final Category category) {
if (pageable.getSort().getOrderFor(REVIEW_COUNT) != null) {
if (Objects.nonNull(pageable.getSort().getOrderFor(REVIEW_COUNT))) {
final PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize());
return productRepository.findAllByCategoryOrderByReviewCountDesc(category, pageRequest);
}
Expand All @@ -106,7 +108,7 @@ public RankingProductsResponse getTop3Products() {

final List<RankingProductDto> rankingProductDtos = productsAndReviewCounts.stream()
.sorted(rankingScoreComparator)
.limit(3)
.limit(RANKING_SIZE)
.map(it -> RankingProductDto.toDto(it.getProduct()))
.collect(Collectors.toList());

Expand All @@ -125,7 +127,8 @@ public SearchProductsResponse searchProducts(final String query, final Pageable
}

public SearchProductResultsResponse getSearchResults(final String query, final Pageable pageable) {
final Page<ProductReviewCountDto> products = productRepository.findAllWithReviewCountByNameContaining(query, pageable);
final Page<ProductReviewCountDto> products = productRepository.findAllWithReviewCountByNameContaining(query,
pageable);

final PageDto pageDto = PageDto.toDto(products);
final List<SearchProductResultDto> resultDtos = products.stream()
Expand Down
Loading

0 comments on commit 8a8e042

Please sign in to comment.