-
Notifications
You must be signed in to change notification settings - Fork 25
[윤해인_BackEnd] 10주차 과제 제출합니다. #36
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
base: main
Are you sure you want to change the base?
Changes from all commits
2be6659
ef40bb1
f91348e
8c85ccd
1929b23
3ca1877
bea25b7
421f6cf
bba018e
685259a
973e141
832dabe
0e4a15f
dd15a17
6fcc41a
5137891
e99147c
267f349
8fc22c3
39592fb
3102c7e
bc42497
e0a827d
e63da7e
04f2fb0
048b34f
a0f0c62
577d88c
2c39380
9737281
1392bb5
2a2f42c
e656ece
442ca10
d8d580c
6ef2a24
0f23e4d
761fdd9
a92300a
f256dc4
102741f
0b3a894
7532a79
6ed39c0
584c45c
2ac2e2f
4fc9db8
31c6853
4d1d3e8
b0cc9ea
f576b72
c8ca023
5455de2
64be0c4
0a4351b
8f37f46
9103f74
37b4ea3
2af9bcd
fc74925
80d0c44
98bab15
709f5b7
b55b520
73f2cca
da2d39e
8cbe136
4fc91c8
b67e4f9
0feaa17
07d590b
c943699
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # BCSD_BackEnd25-2-week10 | ||
| 비기너 10주차까지의 과제 백업 |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| package com.example.bcsd.config; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||
| import org.springframework.security.config.http.SessionCreationPolicy; | ||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
| import org.springframework.security.web.SecurityFilterChain; | ||
| import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
| import org.springframework.web.cors.CorsConfiguration; | ||
| import org.springframework.web.cors.reactive.CorsConfigurationSource; | ||
|
|
||
| import java.util.Collections; | ||
|
|
||
| @RequiredArgsConstructor | ||
| @Configuration | ||
| public class SecurityConfig { | ||
| @Bean | ||
| public BCryptPasswordEncoder passwordEncoder() { | ||
| return new BCryptPasswordEncoder(); | ||
| } | ||
|
|
||
| @Bean | ||
| public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||
| http | ||
| .csrf(csrf -> csrf.disable()) // JWT 사용하므로 비활성화 | ||
| .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) | ||
|
|
||
| // 엔드포인트별 접근 권한 설정 | ||
| .authorizeHttpRequests(auth -> auth | ||
| .requestMatchers("/auth/**").permitAll() // 로그인/회원가입은 열어두어야 접근 가능함... | ||
| .anyRequest().authenticated() // 이외 요청은 인증된 사용자만 접근 가능 | ||
| ) | ||
| .httpBasic(AbstractHttpConfigurer::disable) // Basic Auth 끄기 | ||
| // JWT 필터 추가 (기존 UsernamePasswordAuthenticationFilter 이전에 실행) | ||
| .addFilterBefore(new JWTFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class) | ||
|
|
||
| // 로그인 필터 추가 (JWTFilter 실행 후 JWT 발급 처리) | ||
| .addFilterAfter(new LoginFilter(authenticationManager(), jwtUtil), JWTFilter.class) | ||
|
|
||
| // 세션을 사용하지 않음 (JWT 기반 인증이므로 STATELESS 모드 설정) | ||
| .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); | ||
|
|
||
| return http.build(); | ||
| } | ||
|
|
||
| // 프론트용 | ||
| @Bean | ||
| public CorsConfigurationSource corsConfigurationSource() { | ||
| return request -> { | ||
| CorsConfiguration configuration = new CorsConfiguration(); | ||
| configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); // 허용할 도메인 | ||
| configuration.setAllowedMethods(Collections.singletonList("*")); // 모든 HTTP 메서드 허용 | ||
| configuration.setAllowCredentials(true); // 인증 정보 포함 허용 | ||
| configuration.setAllowedHeaders(Collections.singletonList("*")); // 모든 헤더 허용 | ||
| configuration.setExposedHeaders(Collections.singletonList("Authorization")); // Authorization 헤더 노출 | ||
| configuration.setMaxAge(3600L); // 1시간 동안 캐싱 | ||
| return configuration; | ||
| }; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| package com.example.bcsd.controller; | ||
|
|
||
| import com.example.bcsd.domain.Article; | ||
| import com.example.bcsd.dto.ArticleDTO; | ||
|
|
||
| import com.example.bcsd.dto.ArticleResponse; | ||
| import com.example.bcsd.service.ArticleService; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/articles") | ||
| public class ArticleApiController { | ||
| private final ArticleService articleService; | ||
|
|
||
| public ArticleApiController(ArticleService articleService) { | ||
| this.articleService = articleService; | ||
| } | ||
|
|
||
| // 1. POST /articles : 게시글 저장하기 | ||
| @PostMapping | ||
| public Article create(@RequestBody ArticleDTO req){ // ?? | ||
| return articleService.create(req); | ||
| } | ||
|
|
||
| // 2. GET /articles?boardId={boardId} : 한 게시판의 모든 article 조회하기 | ||
| @GetMapping | ||
| public List<Article> getAllArticlesByBoard(@RequestParam(required = false) Long boardId){ | ||
| return articleService.getAllArticlesByBoard(boardId); | ||
| } | ||
| @GetMapping("/by-board") | ||
| public List<ArticleResponse> getByBoard(@RequestParam Long boardId) { | ||
| return articleService.getAllArticlesByBoard(boardId) | ||
| .stream() | ||
| .map(ArticleResponse::from) | ||
| .toList(); | ||
| } | ||
| // 3. GET /articles/{id} : 아이디로 article 찾기 | ||
| @GetMapping("/{id}") | ||
| public Article getOne(@PathVariable Long id){ | ||
| return articleService.getOne(id); | ||
| } | ||
|
|
||
| // 4. PUT : 게시글 수정하기 | ||
| @PutMapping("/{id}") | ||
| public Article update(@PathVariable Long id, | ||
| @RequestBody ArticleDTO req){ | ||
| return articleService.update(req, id); | ||
| } | ||
|
|
||
| // 5. DELETE /articles/{id} : id로 삭제하기 | ||
| @DeleteMapping("/{id}") | ||
| public ResponseEntity<Void> delete(@PathVariable Long id) { | ||
| articleService.delete(id); | ||
| // 예외는 service에서만! | ||
| return ResponseEntity.noContent().build(); // 204 | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package com.example.bcsd.controller; | ||
|
|
||
| import com.example.bcsd.dto.MemberDTO; | ||
| import com.example.bcsd.service.MemberService; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/auth") | ||
| public class AuthController { | ||
|
|
||
| private final MemberService memberService; | ||
|
|
||
| public AuthController(MemberService memberService) { | ||
| this.memberService = memberService; | ||
| } | ||
|
|
||
| @PostMapping("/login") | ||
| public ResponseEntity<String> login(@RequestBody MemberDTO req) { | ||
| memberService.login(req); | ||
| return ResponseEntity.ok("login success"); | ||
| } | ||
|
|
||
| @PostMapping("/signup") | ||
| public ResponseEntity<String> signup(@RequestBody MemberDTO req) { | ||
| memberService.signup(req); | ||
| return ResponseEntity.ok("signup success"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package com.example.bcsd.controller; | ||
|
|
||
| import com.example.bcsd.domain.Board; | ||
| import com.example.bcsd.dto.BoardDTO; | ||
| import com.example.bcsd.dto.BoardResponse; | ||
| import com.example.bcsd.service.BoardService; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/board") | ||
| public class BoardController { | ||
| private final BoardService boardService; | ||
|
|
||
| public BoardController(BoardService boardService) { | ||
| this.boardService = boardService; | ||
| } | ||
|
|
||
| // 1. POST /board : 게시판 신규 생성하기 | ||
| @PostMapping | ||
| public Board create(@RequestBody BoardDTO req){ | ||
| return boardService.create(req); | ||
| } | ||
|
|
||
| // 2. DELETE /boardId/{id} : 게시판 id로 삭제하기 | ||
| @DeleteMapping("/{id}") | ||
| public ResponseEntity<Void> delete(@PathVariable Long id) { | ||
| boardService.delete(id); | ||
| return ResponseEntity.noContent().build(); // 204 | ||
| } | ||
|
|
||
| // 3. GET /board/{id} : 게시판 id로 게시글 조회하기 | ||
| @GetMapping("/{id}") | ||
| public BoardResponse getOne(@PathVariable Long id) { | ||
| // return boardService.getOne(id); | ||
| return BoardResponse.from(boardService.getOne(id)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // controller는 어떤 로직을 호출할건지 요청을 받는다. | ||
| // 즉, controller -> service | ||
| package com.example.bcsd.controller; | ||
|
|
||
| import com.example.bcsd.dto.HelloDTO; | ||
| import org.springframework.stereotype.Controller; | ||
| import org.springframework.ui.Model; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
| import org.springframework.web.bind.annotation.ResponseBody; | ||
|
|
||
|
|
||
| @Controller | ||
| @RequestMapping("/introduce") | ||
| public class HelloController { | ||
|
|
||
| // 1) /introduce/html -> introduce.html 반환 | ||
| @GetMapping("/html") | ||
| public String hello(Model model) { | ||
| return "introduce"; | ||
| } | ||
|
|
||
| // 2) /introduce/string?name=이름 -> "안녕하세요. 제 이름은 000 입니다." | ||
| @GetMapping("/string") | ||
| public String introduceString(@RequestParam String name, Model model) { | ||
| model.addAttribute("name", name); | ||
| return "greeting"; | ||
| } | ||
|
|
||
| // 3) /json에 json형태로 반환 | ||
| @GetMapping("/json") | ||
| @ResponseBody | ||
| // <1> Map으로 JSON 수제로 만들기 -- 권장되는 방법이 아님 | ||
| // public Map<String, Object> introduceJson() { | ||
| // return helloService.getHelloJson(); | ||
| // } | ||
| // <2> 객체를 통해 JSON 자동 반환하기★ | ||
| public HelloDTO getJson(){ | ||
| HelloDTO hello = new HelloDTO(); | ||
| hello.setAge(24); | ||
| hello.setName("윤해인"); | ||
| return hello; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| package com.example.bcsd.controller; | ||
|
|
||
| import com.example.bcsd.domain.Member; | ||
| import com.example.bcsd.dto.MemberDTO; | ||
| import com.example.bcsd.service.MemberService; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/members") | ||
| public class MemberController { | ||
|
|
||
| private final MemberService memberService; | ||
|
|
||
| @Autowired | ||
| public MemberController(MemberService memberService) { | ||
| this.memberService = memberService; | ||
| } | ||
|
|
||
| // 1. member 생성 | ||
| @PostMapping | ||
| public Member create(@RequestBody MemberDTO req) { | ||
| return memberService.create(req); | ||
| } | ||
|
|
||
| // 2. member 정보 수정 | ||
| @PutMapping("/{id}") | ||
| public Member update(@PathVariable Long id, | ||
| @RequestBody MemberDTO req) { | ||
| return memberService.update(req, id); | ||
| } | ||
|
|
||
| // 3. member 삭제 | ||
| @DeleteMapping("/{id}") | ||
| public ResponseEntity<Void> delete(@PathVariable Long id) { | ||
| memberService.delete(id); | ||
| return ResponseEntity.noContent().build(); // 204 | ||
| } | ||
|
|
||
| // 4. member 조회 | ||
| // 4-1. id로 조회 | ||
| @GetMapping("/{id}") | ||
| public Member getOne(@PathVariable Long id) { | ||
| return memberService.getOne(id); | ||
| } | ||
|
|
||
| // 4-2. name으로 조회 | ||
| @GetMapping("/search") | ||
| public List<Member> searchByName(@RequestParam String name) { | ||
| return memberService.searchByName(name); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package com.example.bcsd.controller; | ||
|
|
||
| import com.example.bcsd.service.ArticleService; | ||
| import com.example.bcsd.service.BoardService; | ||
|
|
||
| import org.springframework.stereotype.Controller; | ||
| import org.springframework.ui.Model; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
|
|
||
| @Controller | ||
| @RequestMapping("/posts") // /posts?boardId={boardId} | ||
| public class PostController { | ||
| private final BoardService boardService; | ||
| private final ArticleService articleService; | ||
|
|
||
| public PostController(ArticleService articleService, BoardService boardService) { | ||
| this.boardService = boardService; | ||
| this.articleService = articleService; | ||
| } | ||
|
Comment on lines
+17
to
21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lombok라이브러리를 한번 알아봐보셔도 좋을거같아요.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lombok이 getter와 setter, 생성자를 대체할 수 있다-까지는 확인했는데, 아직은 실제로 써보는게 좋을 것 같아 그대로 두었습니다. |
||
|
|
||
| @GetMapping | ||
| public String posts(@RequestParam("boardId") Long boardId, Model model) { | ||
| String boardName = boardService.getBoardName(boardId); | ||
| model.addAttribute("boardName", boardName); | ||
| model.addAttribute("articles", articleService.getAllArticlesByBoard(boardId)); | ||
| return "posts"; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Controller의 메서드명이 조금더 명확해도 좋을거같아요
아이디로 삭제 : delete -> deleteById
아이디로 Article 조회 : getOne -> getById
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
참고하여 리팩토링 진행하겠습니다. 감사합니다!