Skip to content

Commit d6f2979

Browse files
authored
Merge pull request #112 from RealPawParazzi/feature/111/RefactorCode
[Refactor] 멤버, 게시물, 좋아요 controller, service 분리
2 parents 0b5de9d + 9747e75 commit d6f2979

7 files changed

Lines changed: 80 additions & 134 deletions

File tree

Lines changed: 11 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
package pawparazzi.back.board.controller;
22

3-
import com.fasterxml.jackson.core.JsonProcessingException;
4-
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import io.jsonwebtoken.JwtException;
63
import lombok.RequiredArgsConstructor;
7-
import org.springframework.http.HttpStatus;
84
import org.springframework.http.MediaType;
95
import org.springframework.http.ResponseEntity;
6+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
107
import org.springframework.web.bind.annotation.*;
118
import org.springframework.web.multipart.MultipartFile;
12-
import pawparazzi.back.board.dto.BoardCreateRequestDto;
139
import pawparazzi.back.board.dto.BoardListResponseDto;
1410
import pawparazzi.back.board.dto.BoardDetailDto;
15-
import pawparazzi.back.board.dto.BoardUpdateRequestDto;
1611
import pawparazzi.back.board.service.BoardService;
17-
import pawparazzi.back.security.util.JwtUtil;
12+
import pawparazzi.back.security.user.CustomUserDetails;
1813

1914
import java.util.List;
2015

@@ -24,37 +19,21 @@
2419
public class BoardController {
2520

2621
private final BoardService boardService;
27-
private final JwtUtil jwtUtil;
28-
private final ObjectMapper objectMapper;
2922

3023
/**
3124
* 게시물 등록
3225
*/
3326
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
3427
public ResponseEntity<BoardDetailDto> createBoard(
35-
@RequestHeader("Authorization") String token,
28+
@AuthenticationPrincipal CustomUserDetails userDetails,
3629
@RequestPart("userData") String userDataJson,
3730
@RequestPart(value = "mediaFiles", required = false) List<MultipartFile> mediaFiles,
3831
@RequestPart(value = "titleImage", required = false) MultipartFile titleImageFile,
3932
@RequestPart(value = "titleContent", required = false) String titleContent) {
4033

41-
Long memberId;
42-
try {
43-
memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
44-
} catch (JwtException e) {
45-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
46-
}
34+
Long memberId = userDetails.getId();
4735

48-
BoardCreateRequestDto requestDto;
49-
try {
50-
requestDto = objectMapper.readValue(userDataJson, BoardCreateRequestDto.class);
51-
requestDto.setMediaFiles(mediaFiles);
52-
requestDto.setTitleContent(titleContent);
53-
} catch (JsonProcessingException e) {
54-
return ResponseEntity.badRequest().body(null);
55-
}
56-
57-
BoardDetailDto response = boardService.createBoard(requestDto, memberId, titleImageFile);
36+
BoardDetailDto response = boardService.createBoard(userDataJson, memberId, titleImageFile, mediaFiles, titleContent);
5837
return ResponseEntity.ok(response);
5938
}
6039

@@ -82,30 +61,16 @@ public ResponseEntity<List<BoardListResponseDto>> getBoardList() {
8261
@PutMapping(value = "/{boardId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
8362
public ResponseEntity<BoardDetailDto> updateBoard(
8463
@PathVariable Long boardId,
85-
@RequestHeader("Authorization") String token,
64+
@AuthenticationPrincipal CustomUserDetails userDetails,
8665
@RequestPart("userData") String userDataJson,
8766
@RequestPart(value = "mediaFiles", required = false) List<MultipartFile> mediaFiles,
8867
@RequestPart(value = "titleImage", required = false) MultipartFile titleImageFile,
8968
@RequestPart(value = "titleContent", required = false) String titleContent) {
9069

91-
Long memberId;
92-
try {
93-
memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
94-
} catch (JwtException e) {
95-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
96-
}
97-
98-
try {
99-
BoardUpdateRequestDto requestDto = objectMapper.readValue(userDataJson, BoardUpdateRequestDto.class);
100-
101-
requestDto.setTitleContent(titleContent);
70+
Long memberId = userDetails.getId();
10271

103-
BoardDetailDto updatedBoard = boardService.updateBoard(boardId, memberId, requestDto, mediaFiles, titleImageFile).join();
104-
105-
return ResponseEntity.ok(updatedBoard);
106-
} catch (JsonProcessingException e) {
107-
return ResponseEntity.badRequest().body(null);
108-
}
72+
BoardDetailDto updatedBoard = boardService.updateBoard(boardId, memberId, userDataJson, mediaFiles, titleImageFile, titleContent).join();
73+
return ResponseEntity.ok(updatedBoard);
10974
}
11075

11176
/**
@@ -121,16 +86,10 @@ public ResponseEntity<List<BoardListResponseDto>> getBoardsByMember(@PathVariabl
12186
* 게시물 삭제
12287
*/
12388
@DeleteMapping("/{boardId}")
124-
public ResponseEntity<Void> deleteBoard(@PathVariable Long boardId, @RequestHeader("Authorization") String token) {
125-
Long userId;
126-
try {
127-
userId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
128-
} catch (JwtException e) {
129-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
130-
}
89+
public ResponseEntity<Void> deleteBoard(@PathVariable Long boardId, @AuthenticationPrincipal CustomUserDetails userDetails) {
90+
Long userId = userDetails.getId();
13191

13292
boardService.deleteBoard(boardId, userId).join();
133-
13493
return ResponseEntity.noContent().build();
13594
}
13695
}

src/main/java/pawparazzi/back/board/service/BoardService.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package pawparazzi.back.board.service;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
35
import jakarta.persistence.EntityNotFoundException;
46
import lombok.RequiredArgsConstructor;
57
import org.springframework.stereotype.Service;
@@ -48,7 +50,16 @@ public class BoardService {
4850
* 게시물 등록
4951
*/
5052
@Transactional
51-
public BoardDetailDto createBoard(BoardCreateRequestDto requestDto, Long userId, MultipartFile titleImageFile) {
53+
public BoardDetailDto createBoard(String userDataJson, Long userId, MultipartFile titleImageFile, List<MultipartFile> mediaFiles, String titleContent) {
54+
BoardCreateRequestDto requestDto;
55+
try {
56+
requestDto = new ObjectMapper().readValue(userDataJson, BoardCreateRequestDto.class);
57+
} catch (JsonProcessingException e) {
58+
throw new IllegalArgumentException("Invalid JSON format", e);
59+
}
60+
requestDto.setMediaFiles(mediaFiles);
61+
requestDto.setTitleContent(titleContent);
62+
5263
Member member = memberRepository.findById(userId)
5364
.orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다."));
5465

@@ -131,10 +142,15 @@ private String getTitleImageUrl(MultipartFile titleImageFile, List<String> uploa
131142
* 게시물 수정
132143
*/
133144
@Transactional
134-
public CompletableFuture<BoardDetailDto> updateBoard(Long boardId, Long userId,
135-
BoardUpdateRequestDto requestDto,
136-
List<MultipartFile> mediaFiles,
137-
MultipartFile titleImageFile) {
145+
public CompletableFuture<BoardDetailDto> updateBoard(Long boardId, Long userId, String userDataJson, List<MultipartFile> mediaFiles, MultipartFile titleImageFile, String titleContent) {
146+
BoardUpdateRequestDto requestDto;
147+
try {
148+
requestDto = new ObjectMapper().readValue(userDataJson, BoardUpdateRequestDto.class);
149+
} catch (JsonProcessingException e) {
150+
throw new IllegalArgumentException("Invalid JSON format", e);
151+
}
152+
requestDto.setTitleContent(titleContent);
153+
138154
Board board = boardRepository.findById(boardId)
139155
.orElseThrow(() -> new EntityNotFoundException("게시물을 찾을 수 없습니다."));
140156

src/main/java/pawparazzi/back/likes/controller/LikeController.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import pawparazzi.back.likes.dto.LikeResponseDto;
1010
import pawparazzi.back.likes.dto.LikeToggleResponseDto;
1111
import pawparazzi.back.likes.service.LikeService;
12-
import pawparazzi.back.security.util.JwtUtil;
12+
import pawparazzi.back.security.user.CustomUserDetails;
1313

1414
import java.util.List;
1515
import java.util.Map;
@@ -20,22 +20,16 @@
2020
public class LikeController {
2121

2222
private final LikeService likeService;
23-
private final JwtUtil jwtUtil;
2423

2524
/**
2625
* 좋아요 등록/삭제
2726
*/
2827
@PostMapping("/{boardId}/like")
2928
public ResponseEntity<LikeToggleResponseDto> toggleLike(
3029
@PathVariable Long boardId,
31-
@RequestHeader("Authorization") String token) {
32-
33-
Long memberId;
34-
try {
35-
memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
36-
} catch (JwtException e) {
37-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
38-
}
30+
@AuthenticationPrincipal CustomUserDetails userDetails) {
31+
32+
Long memberId = userDetails.getId();
3933
LikeToggleResponseDto response = likeService.toggleLike(boardId, memberId);
4034

4135
return ResponseEntity.ok(response);

src/main/java/pawparazzi/back/member/controller/MemberController.java

Lines changed: 16 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
11
package pawparazzi.back.member.controller;
22

3-
import com.fasterxml.jackson.core.JsonProcessingException;
4-
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import io.jsonwebtoken.JwtException;
63
import jakarta.validation.Valid;
74
import lombok.RequiredArgsConstructor;
8-
import org.springframework.http.HttpStatus;
95
import org.springframework.http.MediaType;
106
import org.springframework.http.ResponseEntity;
7+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
118
import org.springframework.web.bind.annotation.*;
129
import org.springframework.web.multipart.MultipartFile;
1310
import pawparazzi.back.member.dto.request.LoginRequestDto;
14-
import pawparazzi.back.member.dto.request.SignUpRequestDto;
15-
import pawparazzi.back.member.dto.request.UpdateMemberRequestDto;
1611
import pawparazzi.back.member.dto.response.MemberResponseDto;
1712
import pawparazzi.back.member.dto.response.UpdateMemberResponseDto;
1813
import pawparazzi.back.member.entity.Member;
1914
import pawparazzi.back.member.service.MemberService;
20-
import pawparazzi.back.security.util.JwtUtil;
15+
import pawparazzi.back.security.user.CustomUserDetails;
2116

2217
import java.util.List;
2318
import java.util.Map;
@@ -28,9 +23,7 @@
2823
@RequiredArgsConstructor
2924
public class MemberController {
3025

31-
private final JwtUtil jwtUtil;
3226
private final MemberService memberService;
33-
private final ObjectMapper objectMapper;
3427

3528
/**
3629
* 회원 가입
@@ -40,17 +33,10 @@ public CompletableFuture<ResponseEntity<String>> registerUser(
4033
@RequestPart(value = "profileImage", required = false) MultipartFile profileImage,
4134
@RequestPart("userData") String userDataJson) {
4235

43-
// JSON 데이터를 DTO로 변환
44-
SignUpRequestDto request;
45-
try {
46-
request = objectMapper.readValue(userDataJson, SignUpRequestDto.class);
47-
} catch (JsonProcessingException e) {
48-
return CompletableFuture.completedFuture(ResponseEntity.badRequest().body("Invalid JSON format"));
49-
}
50-
5136
// 비동기 회원가입 처리 후 응답 반환
52-
return memberService.registerUser(request, profileImage)
53-
.thenApply(unused -> ResponseEntity.ok("회원가입 성공"));
37+
return memberService.registerUser(userDataJson, profileImage)
38+
.thenApply(unused -> ResponseEntity.ok("회원가입 성공"))
39+
.exceptionally(ex -> ResponseEntity.badRequest().body("Invalid JSON format"));
5440
}
5541

5642
/**
@@ -66,14 +52,8 @@ public ResponseEntity<Map<String, String>> login(@Valid @RequestBody LoginReques
6652
* 사용자 정보 조회
6753
*/
6854
@GetMapping("/me")
69-
public ResponseEntity<Member> getCurrentUser(@RequestHeader("Authorization") String token) {
70-
token = token.replace("Bearer ", "");
71-
Long memberId;
72-
try {
73-
memberId = jwtUtil.extractMemberId(token);
74-
} catch (JwtException e) {
75-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
76-
}
55+
public ResponseEntity<Member> getCurrentUser(@AuthenticationPrincipal CustomUserDetails userDetails) {
56+
Long memberId = userDetails.getId();
7757
Member member = memberService.findById(memberId);
7858
return ResponseEntity.ok(member);
7959
}
@@ -83,43 +63,23 @@ public ResponseEntity<Member> getCurrentUser(@RequestHeader("Authorization") Str
8363
*/
8464
@PatchMapping(value = "/me", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
8565
public CompletableFuture<ResponseEntity<UpdateMemberResponseDto>> updateMember(
86-
@RequestHeader("Authorization") String token,
66+
@AuthenticationPrincipal CustomUserDetails userDetails,
8767
@RequestPart(value = "profileImage", required = false) MultipartFile profileImage,
8868
@RequestPart(value = "userData", required = false) String userDataJson) {
8969

90-
token = token.replace("Bearer ", "");
91-
Long memberId;
92-
try {
93-
memberId = jwtUtil.extractMemberId(token);
94-
} catch (JwtException e) {
95-
return CompletableFuture.completedFuture(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build());
96-
}
97-
98-
try {
99-
UpdateMemberRequestDto request = (userDataJson == null || userDataJson.isBlank())
100-
? new UpdateMemberRequestDto()
101-
: objectMapper.readValue(userDataJson, UpdateMemberRequestDto.class);
70+
Long memberId = userDetails.getId();
10271

103-
return memberService.updateMember(memberId, request, profileImage)
104-
.thenApply(ResponseEntity::ok);
105-
} catch (JsonProcessingException e) {
106-
return CompletableFuture.completedFuture(ResponseEntity.badRequest().body(null));
107-
}
72+
return memberService.updateMember(memberId, userDataJson, profileImage)
73+
.thenApply(ResponseEntity::ok)
74+
.exceptionally(ex -> ResponseEntity.badRequest().body(null));
10875
}
10976

11077
/**
11178
* 회원 탈퇴
11279
*/
11380
@DeleteMapping("/delete")
114-
public ResponseEntity<String> deleteMember(@RequestHeader("Authorization") String token) {
115-
token = token.replace("Bearer ", "");
116-
Long memberId;
117-
try {
118-
memberId = jwtUtil.extractMemberId(token);
119-
} catch (JwtException e) {
120-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
121-
}
122-
memberService.deleteMember(memberId);
81+
public ResponseEntity<String> deleteMember(@AuthenticationPrincipal CustomUserDetails userDetails) {
82+
memberService.deleteMember(userDetails.getId());
12383
return ResponseEntity.ok("회원 탈퇴 완료");
12484
}
12585

@@ -136,17 +96,10 @@ public ResponseEntity<List<MemberResponseDto>> getAllMembers() {
13696
* 로그아웃
13797
*/
13898
@PostMapping("/logout")
139-
public ResponseEntity<String> logout(@RequestHeader("Authorization") String accessToken,
99+
public ResponseEntity<String> logout(@AuthenticationPrincipal CustomUserDetails userDetails,
140100
@RequestBody Map<String, String> body) {
141101
String refreshToken = body.get("refreshToken");
142-
accessToken = accessToken.replace("Bearer ", "");
143-
Long memberId;
144-
try {
145-
memberId = jwtUtil.extractMemberId(accessToken);
146-
} catch (JwtException e) {
147-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
148-
}
149-
memberService.logout(memberId, refreshToken);
102+
memberService.logout(userDetails.getId(), refreshToken);
150103
return ResponseEntity.ok("로그아웃 완료");
151104
}
152105

0 commit comments

Comments
 (0)