Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
92bf962
introduce.html 완성
dldb-chamchi May 4, 2025
7a993e0
feat: /introduce 요청시 자기소개 반환
dldb-chamchi May 4, 2025
f0c4a94
feat: /introduce?name={} 요청시 이름 설정 값을 반한
dldb-chamchi May 4, 2025
6425094
feat: json 요청시 반환
dldb-chamchi May 4, 2025
c43e1ca
feat: Article 클래스 생성
dldb-chamchi May 5, 2025
3c2724b
feat: CRUD API 작성
dldb-chamchi May 5, 2025
7028773
fix: ArticleController 수정
dldb-chamchi May 5, 2025
baf7b48
fix: IntroduceController 수정
dldb-chamchi May 5, 2025
ed73b94
fix: Article 멤버변수 추가
dldb-chamchi May 11, 2025
120da72
feat: ArticleService 추가
dldb-chamchi May 11, 2025
5f424c5
feat: Model-Board 추가
dldb-chamchi May 11, 2025
cf63e95
feat: Model-Member 추가
dldb-chamchi May 11, 2025
d8c968b
feat: Service-BoardService 추가
dldb-chamchi May 11, 2025
3ad5095
feat: Repository-ArticleRepository 추가
dldb-chamchi May 11, 2025
19ed6cb
feat: Repository-BoardRepository 추가
dldb-chamchi May 11, 2025
6e39317
fix: ArticleController 수정
dldb-chamchi May 11, 2025
5c1a0e9
feat: PostsController
dldb-chamchi May 11, 2025
42aa007
fix: ArticleRepository
dldb-chamchi May 19, 2025
b9cd0e7
feat: BoardRepository
dldb-chamchi May 19, 2025
8aee1c9
feat: BoardService
dldb-chamchi May 19, 2025
b63c6eb
feat: BoardDao
dldb-chamchi May 19, 2025
f37c5f5
feat: ArticleDto
dldb-chamchi May 19, 2025
8ad5885
fix: 자바 컨벤션
dldb-chamchi May 19, 2025
2364e0b
fix: 트랜잭션 어노테이션 추가
dldb-chamchi May 19, 2025
8840e24
feat: BoardController
dldb-chamchi May 23, 2025
281e2ce
feat: BoardController
dldb-chamchi May 23, 2025
d8374a8
fix: PostsController dto로 넘겨주기
dldb-chamchi May 23, 2025
20faa12
feat: MemberDto
dldb-chamchi May 23, 2025
033ef20
feat: BadRequestException
dldb-chamchi May 23, 2025
052047e
feat: DuplicateEmailException
dldb-chamchi May 23, 2025
a00b251
feat: ErrorResponse
dldb-chamchi May 23, 2025
2cd6a3a
feat: ResourceNotFoundException.
dldb-chamchi May 23, 2025
e27644e
feat: GlobalExceptionHandler
dldb-chamchi May 23, 2025
6c93c20
fix: convention
dldb-chamchi May 23, 2025
ab72204
fix: convention
dldb-chamchi May 23, 2025
1a6b02b
feat: Member
dldb-chamchi May 23, 2025
6a88c50
feat: ArticleService
dldb-chamchi May 23, 2025
35c9fae
feat: BoardService
dldb-chamchi May 23, 2025
061d353
feat: MemberService
dldb-chamchi May 23, 2025
a4448da
fix: MemberRepository 구조 수정
dldb-chamchi May 23, 2025
1ee0f80
feat: MemberRepostiory
dldb-chamchi May 23, 2025
27d3491
fix: 전체 코드 컨벤션 수정
dldb-chamchi May 23, 2025
fca0bcc
fix: 안쓰는 코드 수정
dldb-chamchi May 23, 2025
60455ed
fix: 컨벤션 및 로직 수정
dldb-chamchi May 24, 2025
0717576
fix: JPA Article 추가
dldb-chamchi May 28, 2025
5cf53fc
fix: JPA Board 추가
dldb-chamchi May 28, 2025
7204033
fix: JPA Member 추가
dldb-chamchi May 28, 2025
edd0da3
fix: JPA ArticleRepository 추가:
dldb-chamchi May 28, 2025
e180d0d
fix: JPA BoardRepository
dldb-chamchi May 28, 2025
4a4dbcd
fix: JPA MemberRepository
dldb-chamchi May 28, 2025
383797b
fix: 컨벤션 수정
dldb-chamchi May 28, 2025
d262225
fix: RequestDto, ResponseDto 로직 수정
dldb-chamchi Jun 14, 2025
12a0a9c
fix: Lombok 설정
dldb-chamchi Jun 17, 2025
6717258
feat: 연관관계 추가
dldb-chamchi Jun 17, 2025
7951f0e
fix: Lombok 설정
dldb-chamchi Jun 17, 2025
051a10d
feat: 연관관계 추가
dldb-chamchi Jun 17, 2025
4d03ce0
fix: Lombok 설정
dldb-chamchi Jun 17, 2025
2b8f70d
fix: Dto Controller 수정
dldb-chamchi Jun 17, 2025
9220f14
fix: Dto Controller 수정
dldb-chamchi Jun 17, 2025
1ee5645
fix: JPA로 수정
dldb-chamchi Jun 17, 2025
70d6636
fix: JPA로 수정
dldb-chamchi Jun 17, 2025
0c88940
fix: JPA로 수정
dldb-chamchi Jun 17, 2025
9862d88
fix: JPA로 수정
dldb-chamchi Jun 17, 2025
97692f2
fix: 컨벤션 수정
dldb-chamchi Jun 17, 2025
e99cdf2
fix: 로직 수정
dldb-chamchi Jun 17, 2025
47e7fba
fix: 로직 수정
dldb-chamchi Jun 17, 2025
7669fc3
fix: 로직 수정
dldb-chamchi Jun 17, 2025
834ff62
컨벤션 수정
dldb-chamchi Jun 17, 2025
3384075
feat: Security Config 추가
dldb-chamchi Jun 30, 2025
c1262b3
feat: Securtiy Config 추가2
dldb-chamchi Jun 30, 2025
8e14941
feat: AuthController 추가
dldb-chamchi Jun 30, 2025
87ca57d
feat: LoginRequestDto 추가
dldb-chamchi Jun 30, 2025
84c959b
feat: Member Login Service 추가
dldb-chamchi Jun 30, 2025
7566821
fix: 컨벤션 수정
dldb-chamchi Jun 30, 2025
6f14f55
fix: 컨벤션 수정
dldb-chamchi Jul 6, 2025
7f0804c
fix: 컨벤션 수정 및 주석 수정
dldb-chamchi Jul 6, 2025
cd0b4a6
fix: 주석 수정
dldb-chamchi Jul 7, 2025
58ce88d
fix: 주석 수정
dldb-chamchi Jul 7, 2025
d2ae4ad
refactor: Lombok
dldb-chamchi Jul 7, 2025
d6b9fab
Merge remote-tracking branch 'origin/main'
dldb-chamchi Jul 7, 2025
ee9f454
refactor: Lombok 리팩터링
dldb-chamchi Jul 7, 2025
bbd7b22
refactor: Lombok 리팩터링
dldb-chamchi Jul 7, 2025
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
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'mysql:mysql-connector-java:8.0.33'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
compileOnly 'org.projectlombok:lombok:1.18.28'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
implementation 'org.springframework.boot:spring-boot-starter-security'
}

tasks.named('test') {
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/com/example/bcsd/Json.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.bcsd;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class Json {

public class Introduction {
private int age;
private String name;


public Introduction(int age, String name) {
if(name==null){ throw new RuntimeException();}
this.age = age;
this.name = name;
}

public String getName() {return name;}

public int getAge() {return age;}
}

@GetMapping("/json")
@ResponseBody
public Introduction introduction() {
return new Introduction(26, "허준기");
}
}
14 changes: 14 additions & 0 deletions src/main/java/com/example/bcsd/config/SecurityBeanConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.bcsd.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityBeanConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
55 changes: 55 additions & 0 deletions src/main/java/com/example/bcsd/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.example.bcsd.config;

import com.example.bcsd.service.MemberDetailsService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;

@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
private final MemberDetailsService memberDetailsService;
private final PasswordEncoder passwordEncoder;

@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider p = new DaoAuthenticationProvider();
p.setUserDetailsService(memberDetailsService);
p.setPasswordEncoder(passwordEncoder);
return p;
}

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration cfg) throws Exception {
return cfg.getAuthenticationManager();
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authenticationProvider(authenticationProvider())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/auth/login", "/members").permitAll()
.anyRequest().authenticated()
)
Comment on lines +36 to +44
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인 로그아웃 로직은 의존성을 사용하지 않고 한번쯤 직접 구현해보는 것이 도움이 될 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시간 날 때 한번 직접 구현해보겠습니다!

.logout(logout -> logout
.logoutUrl("/auth/logout")
.permitAll()
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
);
return http.build();
}

}
74 changes: 74 additions & 0 deletions src/main/java/com/example/bcsd/controller/ArticleController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.example.bcsd.controller;

import com.example.bcsd.requestDto.ArticleRequestDto;
import com.example.bcsd.responseDto.ArticleResponseDto;
import com.example.bcsd.model.Article;
import com.example.bcsd.service.ArticleService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/articles")
@RequiredArgsConstructor
public class ArticleController {
private final ArticleService service;

@GetMapping
public ResponseEntity<List<ArticleResponseDto>> getAll() {
List<ArticleResponseDto> dtos = service.getAllArticles().stream()
.map(this::toResponse)
.collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}

@GetMapping("/{id}")
public ResponseEntity<ArticleResponseDto> getById(@PathVariable Long id) {
return service.getArticleById(id)
.map(this::toResponse)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}

@PostMapping
public ResponseEntity<ArticleResponseDto> create(@RequestBody ArticleRequestDto req) {
Article created = service.createArticle(req);
ArticleResponseDto dto = toResponse(created);
return ResponseEntity
.created(URI.create("/articles/" + dto.getId()))
.body(dto);
}

@PutMapping("/{id}")
public ResponseEntity<ArticleResponseDto> update(
@PathVariable Long id,
@RequestBody ArticleRequestDto req
) {
return service.updateArticle(id, req)
.map(this::toResponse)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
return service.deleteArticle(id)
? ResponseEntity.noContent().build() : ResponseEntity.notFound().build();
Comment on lines +58 to +60
Copy link

@kih1015 kih1015 Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

데이터가 존재하지 않는 경우 서비스에서 예외를 던지고

예외 핸들러에서 처리해주는 방법은 어떨까요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그것도 좋은 방법인 것 같습니다. 한번 생각해보겠습니다!

}

private ArticleResponseDto toResponse(Article a) {
return new ArticleResponseDto(
a.getArticleId(),
a.getAuthorId(),
a.getBoard().getBoardId(),
a.getTitle(),
a.getContent(),
a.getWriteDateTime(),
a.getModifyDateTime()
);
}
}
28 changes: 28 additions & 0 deletions src/main/java/com/example/bcsd/controller/AuthController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.example.bcsd.controller;

import com.example.bcsd.requestDto.LoginRequestDto;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {
private final AuthenticationManager authManager;

@PostMapping("/login")
public ResponseEntity<Void> login(@RequestBody LoginRequestDto dto, HttpSession session) {
Authentication auth = authManager.authenticate(
new UsernamePasswordAuthenticationToken(dto.getEmail(), dto.getPassword())
);
SecurityContextHolder.getContext().setAuthentication(auth);
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
return ResponseEntity.ok().build();
}
}
38 changes: 38 additions & 0 deletions src/main/java/com/example/bcsd/controller/BoardController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.bcsd.controller;

import com.example.bcsd.requestDto.BoardRequestDto;
import com.example.bcsd.responseDto.BoardPostsResponseDto;
import com.example.bcsd.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/boards")
@RequiredArgsConstructor
public class BoardController {
private final BoardService boardService;

@PostMapping
public ResponseEntity<Void> createBoard(@RequestBody BoardRequestDto req) {
boardService.createBoard(req);
return ResponseEntity.status(201).build();
}

@GetMapping("/{id}")
public ResponseEntity<BoardPostsResponseDto> getBoard(@PathVariable Long id) {
return ResponseEntity.ok(boardService.getPostsByBoardId(id));
}

@PutMapping("/{id}")
public ResponseEntity<Void> updateBoard(@PathVariable("id") Long id, @RequestBody BoardRequestDto req) {
boardService.updateBoard(id, req);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteBoard(@PathVariable Long id) {
boardService.deleteBoard(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.bcsd;
package com.example.bcsd.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -17,4 +17,5 @@ public String hello() {
public String hello2() {
return "hello";
}

}
12 changes: 12 additions & 0 deletions src/main/java/com/example/bcsd/controller/IntroduceController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.bcsd.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IntroduceController {

@GetMapping(value = "/introduce", params = "!name")
public String Introduce() {return "introduce";}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.bcsd.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IntroduceNameController {

@GetMapping("/introduce")
@ResponseBody
public String introduce(@RequestParam(name = "name") String name) {
return "안녕하세요 제 이름은 " + name + "입니다!";
}

}
66 changes: 66 additions & 0 deletions src/main/java/com/example/bcsd/controller/MemberController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.example.bcsd.controller;

import com.example.bcsd.requestDto.MemberRequestDto;
import com.example.bcsd.responseDto.MemberResponseDto;
import com.example.bcsd.model.Member;
import com.example.bcsd.service.MemberService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;

@RestController
@RequestMapping("/members")
public class MemberController {
private final MemberService memberService;

public MemberController(MemberService memberService) {
this.memberService = memberService;
}

@GetMapping("/{id}")
public ResponseEntity<MemberResponseDto> getById(@PathVariable("id") Long id) {
return memberService.getMemberById(id)
.map(this::toResponse)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}

@PostMapping
public ResponseEntity<MemberResponseDto> create(@RequestBody MemberRequestDto req) {
Member created = memberService.createMember(req);
MemberResponseDto dto = toResponse(created);
return ResponseEntity
.created(URI.create("/members/" + dto.getId()))
.body(dto);
}

@PutMapping("/{id}")
public ResponseEntity<MemberResponseDto> update(
@PathVariable("id") Long id,
@RequestBody MemberRequestDto req
) {
return memberService.updateMember(id, req)
.map(this::toResponse)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable("id") Long id) {
if (memberService.deleteMember(id)) {
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}

private MemberResponseDto toResponse(Member m) {
return new MemberResponseDto(
m.getMemberId().longValue(),
m.getName(),
m.getEmail(),
m.getPassword()
);
}
}
24 changes: 24 additions & 0 deletions src/main/java/com/example/bcsd/controller/PostsController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.bcsd.controller;

import com.example.bcsd.responseDto.BoardPostsResponseDto;
import com.example.bcsd.service.BoardService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class PostsController {
private final BoardService boardService;

public PostsController(BoardService boardService) {
this.boardService = boardService;
}

@GetMapping("/posts")
public String posts(@RequestParam("boardId") Long boardId, Model model) {
BoardPostsResponseDto dto = boardService.getPostsByBoardId(boardId);
model.addAttribute("boardName", dto.getBoardName());
model.addAttribute("articles", dto.getArticles());
return "posts";
}
}
Loading