Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
eae6f16
feat: /introdce 기능 추가
jaechu12 May 5, 2025
a783827
feat: /json 기능 추가
jaechu12 May 5, 2025
7fd9fb9
feat: ?name html 추가
jaechu12 May 5, 2025
b45a041
feat: Article 추가
jaechu12 May 5, 2025
4e6f334
feat: get 기능 추가
jaechu12 May 5, 2025
fcf4402
feat: post 기능 추가
jaechu12 May 5, 2025
7a84d2b
feat: put 기능 추가
jaechu12 May 5, 2025
a90a810
feat: delete 기능 추가
jaechu12 May 5, 2025
96bb334
fix: 함수명 수정
jaechu12 May 12, 2025
e8c7afe
Revert "fix: 함수명 수정"
jaechu12 May 12, 2025
ae9a139
refactor: 함수명 수정
jaechu12 May 12, 2025
f235f6e
feat: /posts 기능 추가
jaechu12 May 12, 2025
6ecd2ab
feat: /articles 기능 추가
jaechu12 May 12, 2025
5d2d1a3
fix: Model 수정
jaechu12 May 12, 2025
6bc7370
feat: Board Model 추가
jaechu12 May 12, 2025
2a494b2
feat: Member Model 추가
jaechu12 May 12, 2025
89fbbac
refactor: map 수정 및 라인 정렬
jaechu12 May 12, 2025
76588c6
fix: DTO 형식으로 수정
jaechu12 May 19, 2025
a611036
fix: Controller 형식으로 수정
jaechu12 May 19, 2025
6b1838b
fix: 바뀐 변수명 적용 및 출력 형태 수정
jaechu12 May 19, 2025
ea335eb
feat: 7차시 요구사항 기능 추가
jaechu12 May 19, 2025
9872851
feat: Service 로직 추가
jaechu12 May 19, 2025
cb2a985
refactor: 미사용 객체 제거
jaechu12 May 26, 2025
7b8562b
fix: DTO 오타 수정
jaechu12 May 26, 2025
278acf0
feat : 요구사항 기능 추가
jaechu12 May 26, 2025
388c926
feat : 요구사항 예외처리 추가
jaechu12 May 26, 2025
8e169c9
refactor : 미사용 객체 제거
jaechu12 May 26, 2025
d6a7922
feat : 예외처리 클래스 추가
jaechu12 May 26, 2025
243e919
feat : JPA 사용
jaechu12 Jun 2, 2025
3081df5
refactor : 폴더 정리
jaechu12 Jun 2, 2025
c3d4f23
refactor : Model 및 DTO 정리
jaechu12 Jun 19, 2025
1f68a0c
refactor : record 사용
jaechu12 Jun 20, 2025
16d8639
refactor : 변경 내용에 맞춰 전체 코드 수정
jaechu12 Jun 20, 2025
89d564c
feat: 영속성 적용
jaechu12 Jun 22, 2025
9edd59f
feat: JPA 적용
jaechu12 Jun 22, 2025
8535516
feat: 로그인 기능 구현
jaechu12 Jun 30, 2025
0e5c866
feat: 회원가입 기능 구현
jaechu12 Jun 30, 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
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
runtimeOnly 'com.mysql:mysql-connector-j'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/example/bcsd/BcsdApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@EnableJpaAuditing
@SpringBootApplication
public class BcsdApplication {

Expand Down
109 changes: 109 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,109 @@
package com.example.bcsd.Controller;

import com.example.bcsd.DTO.ArticleDTO;
import com.example.bcsd.DTO.MemberDTO;
import com.example.bcsd.Model.Article;
import com.example.bcsd.Model.Member;
import com.example.bcsd.Service.ArticleService;
import com.example.bcsd.Service.LoginService;
import com.example.bcsd.SessionConst;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;


@RestController
public class ArticleController {

private final ArticleService articleService;
private final LoginService loginService;

public ArticleController(ArticleService articleService, LoginService loginService) {
this.articleService = articleService;
this.loginService = loginService;
}

@GetMapping("/login")
public String loginForm(HttpServletRequest request, Model model) {
HttpSession session = request.getSession(false);

if (session != null && session.getAttribute(SessionConst.LOGIN_MEMBER) != null) {
model.addAttribute("alreadyLogin", true);
return "loginForm";
}

return "login!";
}

@GetMapping("/articles/{id}")
public ResponseEntity<Article> getArticle(@PathVariable Long id) {
Article article = articleService.getArticle(id);
return ResponseEntity.ok(article);
}

@PostMapping("/login")
public String login(@Valid Member member, BindingResult bindingResult, HttpServletRequest request) throws ServletException {

Member loginMember = loginService.login(member.getEmail(), member.getPassword());
if (loginMember == null) {
return "이메일 또는 비밀번호를 확인해주세요";
}

HttpSession session = request.getSession();

session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
return "로그인되었습니다";
}

@PostMapping("/register")
public ResponseEntity<Member> registMember(@RequestBody Member member) {
Member memberRegist = articleService.registMember(member);
return ResponseEntity.status(HttpStatus.CREATED).body(memberRegist);
}

@PostMapping("/articles")
public ResponseEntity<Article> postArticle(@RequestBody Article articleDTO) {
Article article = articleService.postArticle(articleDTO);
return ResponseEntity.status(HttpStatus.CREATED).body(article);
}


@PutMapping("/articles/{id}")
public ResponseEntity<Article> putArticle(@PathVariable Long id, @RequestBody ArticleDTO updatedArticleDTO) {
Optional<Article> article = articleService.putArticle(id, updatedArticleDTO);
return ResponseEntity.ok(article.get());
}

@PutMapping("/member/{id}")
public ResponseEntity<MemberDTO> putMember(@PathVariable Long id, @RequestBody MemberDTO updatedMemberDTO) {
MemberDTO article = articleService.putMember(id, updatedMemberDTO);
return ResponseEntity.ok(article);
}

@DeleteMapping("/articles/{id}")
public ResponseEntity<String> deleteArticle(@PathVariable Long id) {
ResponseEntity<String> article = articleService.deleteArticle(id);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/member/{id}")
public ResponseEntity<String> deleteMember(@PathVariable Long id) {
ResponseEntity<String> article = articleService.deleteMember(id);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/board/{id}")
public ResponseEntity<String> deleteBoard(@PathVariable Long id) {
ResponseEntity<String> article = articleService.deleteBoard(id);
return ResponseEntity.noContent().build();
}

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

import com.example.bcsd.DTO.ArticleDTO;
import com.example.bcsd.DTO.HelloDTO;
import com.example.bcsd.Model.Article;
import com.example.bcsd.Service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@Controller
public class HelloController {

@Autowired
private JdbcTemplate jdbcTemplate;

private final HelloService helloService;

public HelloController(HelloService helloService) {
this.helloService = helloService;
}

@GetMapping("/introduce")
public String Introduce(@RequestParam(name = "name", required = false) String name, Model model) {
HelloDTO request = new HelloDTO(name);
return helloService.introduceName(request, model);
}

@GetMapping("/json")
@ResponseBody
public HelloDTO json() {
HelloDTO intro = new HelloDTO(26, "허준기");
return intro;
}


@GetMapping("/posts")
public String posts(@RequestParam(name = "boardId") Long boardId, Model model) {
HelloDTO boardPosts = helloService.posts(boardId);

model.addAttribute("boardName", boardPosts.getBoardName());
model.addAttribute("articles", boardPosts.getArticleTitles());

return "posts.html";
}


@GetMapping("/articles")
@ResponseBody
public List<Article> articles(@RequestParam Long boardId) {
return helloService.getboardId(boardId);
}


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

import com.example.bcsd.Model.Article;
import com.example.bcsd.Model.Board;

import java.time.LocalDateTime;
import java.util.Objects;

public record ArticleDTO(
Long id,
Long author,
Long board,
String title,
String content,
LocalDateTime date,
LocalDateTime modifiedDate
) {

public static ArticleDTO from(Article article) {
if (article == null) return null;

return new ArticleDTO(
article.getId(),
article.getAuthor(),
article.getBoard() != null ? article.getBoard().getId() : null,
article.getTitle(),
article.getContent(),
article.getDate(),
article.getModifiedDate()
);
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/example/bcsd/DTO/BoardDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.bcsd.DTO;


import com.example.bcsd.Model.Board;

import java.util.Objects;


public record BoardDTO(
Long id,
String board
) {
public BoardDTO {
Objects.requireNonNull(id);
Objects.requireNonNull(board);
}

public static BoardDTO from(Board board) {
if (board == null) return null;

return new BoardDTO(
board.getId(),
board.getBoard()
);
}
}
45 changes: 45 additions & 0 deletions src/main/java/com/example/bcsd/DTO/HelloDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.example.bcsd.DTO;

import java.util.List;

public class HelloDTO {
private int age;
private String name;
private String boardName;
private Long boardId;
private List<String> articleTitles;


public HelloDTO(int age, String name) {
this.age = age;
this.name = name;
}

public HelloDTO(String name) {
this.name = name;
}

public HelloDTO(String boardName, List<String> articleTitles) {
this.boardName = boardName;
this.articleTitles = articleTitles;
}


public int getAge() {
return age;
}

public String getName() {
return name;
}

public String getBoardName() {
return boardName;
}

public List<String> getArticleTitles() {
return articleTitles;
}


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

import com.example.bcsd.Model.Member;

import java.util.Objects;

public record MemberDTO(
Long id,
String name,
String email,
String password
) {
public MemberDTO {
Objects.requireNonNull(id);
Objects.requireNonNull(name);
Objects.requireNonNull(email);
Objects.requireNonNull(password);
}



public static MemberDTO from(Member member) {
if (member == null) return null;

return new MemberDTO(
member.getID(),
member.getName(),
member.getEmail(),
member.getPassword()
);
}

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

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class globalExceptionHandler {

@ExceptionHandler(EmptyResultDataAccessException.class)
public ResponseEntity<String> handleEmptyResultDataAccessException(
EmptyResultDataAccessException ex
) {
String message = "존재하지 않는 게시물입니다.";
return new ResponseEntity<>(message, HttpStatus.NOT_FOUND);
}

@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<String> handleDataIntegrityViolationException(
DataIntegrityViolationException ex, HttpServletRequest request
) {
String msg = ex.getMostSpecificCause().getMessage();
String method = request.getMethod();

if ("DELETE".equalsIgnoreCase(method) && msg.contains("foreign key constraint")) {
return new ResponseEntity<>("관련된 값이 존재하므로 삭제할 수 없습니다.", HttpStatus.BAD_REQUEST);
}

if ("POST".equalsIgnoreCase(method) && msg.contains("board")) {
return new ResponseEntity<>("존재하지 않는 게시물/게시판입니다.", HttpStatus.BAD_REQUEST);
}

if ("PUT".equalsIgnoreCase(method) && msg.contains("Duplicate entry")) {
return new ResponseEntity<>("중복된 이메일이 존재합니다.", HttpStatus.CONFLICT);
}


return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> handleNullPointerException(
NullPointerException ex
) {
String message = "null이 존재합니다. 입력 데이터를 다시 확인해주세요.";
return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
}

}
Loading