- 0 . . Template
- 1 . Introduction.
- 1 1. . About Spring
- 1 2. . About Spring Boot
- 1 3. . Dev. Environment
- 1 4. . Hello World
- 1 5. . Summary
- 2 . Basic Database.
- 2 1. . MySql & Heidi
- 2 2. . JDBC
- 2 3. . MyBatis
- 2 4. . JPA
- 2 5. . Summary
- 3 . Basic Spring Security.
- 3 1. . About Spring Security
- 3 2. . Signup/Signin/Signout
- 3 3. . Security Information
- 3 4. . Fragment
- 3 5. . Summary
- 4 . Basic Project.
- 4 1. . Question & Answer
- 4 2. . Board & Reply
- 4 3. . Cart & Product
- 4 4. . Buying & Delivery
- 4 5. . Summary
- 5 . Advanced Project.
- 5 1. . Admin
- 5 2. . Chat with Ajax
- 5 3. . Other Login - Korean
- 5 4. . Like & View Count
- 5 5. . Summary
- 6 . Expert Project.
- 6 1. . Map - Korean
- 6 2. . Mail - Korean
- 6 3. . SMS - Korean
- 6 4. . Credit Card - Korean
- 6 5. . Summary
- 7 . Frontend Project.
- 7 1. . HTML/CSS/JS
- 7 2. . Bootstrap
- 7 3. . Theme
- 7 4. . Etc
- 7 5. . Summary
- 8 . Mini Project.
- 8 1. . Storyboard
- 8 2. . Backend - Korean
- 8 3. . Frontend
- 8 4. . Portfolio
- 8 5. . Summary
- 9 . Deploy. Project.
- 9 1. . AWS
- 9 2. . Gabia
- 9 3. . Domain
- 9 4. . Etc
- 9 5. . Summary
- A 1. Bug Repost.
- Appendix 0. .
Board.java
package com.example.projectquestion.board;
import java.time.LocalDateTime;
import java.util.List;
import com.example.projectquestion.customer.Customer;
import com.example.projectquestion.reply.Reply;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import lombok.Data;
@Data
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer bid;
@Column(length = 200)
private String btitle;
@Column(columnDefinition = "TEXT")
private String bcontent;
@ManyToOne//앞 Many 가 나 즉 질문들 뒤가 작성자, 하나의 작성자가 여러 질문을 작성할수 있다.
private Customer bauthor; // User's Object
@OneToMany(mappedBy = "rboard", cascade = CascadeType.REMOVE)
private List<Reply> replyList;
private LocalDateTime bdate;
}
BoardRepository.java
package com.example.projectquestion.board;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BoardRepository extends JpaRepository<Board, Integer> {
}
BoardService / BoardServiceImpl.java
package com.example.projectquestion.board;
import java.security.Principal;
import java.util.List;
public interface BoardService {
void create(Board board, Principal principal);
List<Board> readlist();
Board readdetail (Integer bid);
void update(Board board);
void delete(Integer bid);
}
package com.example.projectquestion.board;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.projectquestion.customer.Customer;
import com.example.projectquestion.customer.CustomerRepository;
@Service
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardRepository boardRepository;
@Autowired
private CustomerRepository customerRepository;
@Override
public void create(Board board, Principal principal) {
board.setBdate(LocalDateTime.now());
Optional<Customer> tc = customerRepository.findByusername(principal.getName());
board.setBauthor(tc.get());
boardRepository.save(board);
}
@Override
public List<Board> readlist() {
return boardRepository.findAll();
}
@Override
public Board readdetail(Integer bid) {
Optional<Board> tb = boardRepository.findById(bid);
return tb.get();
}
@Override
public void update(Board board) {
boardRepository.save(board);
}
@Override
public void delete(Integer bid) {
Optional<Board> tb = boardRepository.findById(bid);
boardRepository.delete(tb.get());
}
}
BoardController
package com.example.projectquestion.board;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/board")
@Controller
public class BoardController {
@Autowired
private BoardService boardService;
@GetMapping("/create")
public String create() {
return "board/create";
}
@PostMapping("/create")
public String create(Board board, Principal principal) {
boardService.create(board, principal);
return "redirect:/board/readlist";
}
@GetMapping("/readlist")
public String readlist(Model model) {
model.addAttribute("boards", boardService.readlist());
return "board/readlist";
}
@GetMapping("/readdetail/{bid}")
public String readdetail(@PathVariable("bid") Integer bid,
Model model) {
model.addAttribute("board", boardService.readdetail(bid));
return "board/readdetail";
}
@GetMapping("/update/{bid}")
public String update(@PathVariable("bid") Integer bid, Model model) {
model.addAttribute("board", boardService.readdetail(bid));
return "board/update";
}
@PostMapping("/update")
public String update(Board board) {
boardService.update(board);
return "redirect:/board/readlist";
}
}
create.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<span sec:authorize="isAnonymous()">Signin First...<a href="/signin">Sign in</a></span>
<span sec:authorize="isAuthenticated()">Welcome...<span th:text="${#authentication.name}"></span>
<span th:text="${#authentication.authorities}"></span>
<a href="/signout">Sign out</a>
</span>
<h1> Board Create </h1>
<form action="/board/create" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<p>Title : <input type="text" name="btitle">
<p>Content : <input type="text" name="bcontent">
<p><input type="submit" value="submit">
</form>
<p><a href="/board/readlist">Board List</a>
</body>
</html>
readlist.html
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1> Read List </h1>
<a href="/board/create">CREATE</a><br><br>
<th:block th:each="board: ${boards}">
[[${board.bid}]] /
<a th:href="@{|/board/readdetail/${board.bid}|}" th:text="${board.btitle}"></a>
/ [[${board.bauthor.username}]] / [[${board.bdate}]]<br>
</th:block>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2> Read Detail </h2>
<a href="/board/readlist">List</a><br><br>
Id : [[${board.bid}]] <br>
Title : [[${board.btitle}]]<br>
Content : [[${board.bcontent}]]<br>
Username : [[${board.bauthor.username}]] <br>
Date : [[${board.bdate}]]<br>
<br><br>
<p><a th:href="@{|/board/update/${board.bid}|}"> update</a>
<p><a th:href="@{|/board/delete/${board.bid}|}"> delete</a>
<br>
<h4>Create Reply</h4>
<form action="/reply/create" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="hidden" name="bid" th:value="${board.bid}"/>
<p>Content : <input type="text" name="rcontent">
<input type="submit" value="create">
</form>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2> Read Detail </h2>
<a href="/board/readlist">List</a><br><br>
Id : [[${board.bid}]] <br>
Title : [[${board.btitle}]]<br>
Content : [[${board.bcontent}]]<br>
Username : [[${board.bauthor.username}]] <br>
Date : [[${board.bdate}]]<br>
<br><br>
<p><a th:href="@{|/board/update/${board.bid}|}"> update</a>
<p><a th:href="@{|/board/delete/${board.bid}|}"> delete</a>
<br>
<h4>Create Reply</h4>
<form action="/reply/create" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="hidden" name="bid" th:value="${board.bid}"/>
<p>Content : <input type="text" name="rcontent">
<input type="submit" value="create">
</form>
Reply.java
package com.example.projectquestion.reply;
import java.time.LocalDateTime;
import com.example.projectquestion.board.Board;
import com.example.projectquestion.customer.Customer;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.Data;
@Data
@Entity
public class Reply {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer rid;
@Column(columnDefinition = "TEXT")
private String rcontent;
@ManyToOne
private Customer rauthor; // User's Object
@ManyToOne
private Board rboard;
private LocalDateTime rdate;
}
package com.example.projectquestion.reply;
import java.time.LocalDateTime;
import com.example.projectquestion.board.Board;
import com.example.projectquestion.customer.Customer;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.Data;
@Data
@Entity
public class Reply {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer rid;
@Column(columnDefinition = "TEXT")
private String rcontent;
@ManyToOne
private Customer rauthor; // User's Object
@ManyToOne
private Board rboard;
private LocalDateTime rdate;
}
ReplyRepository.java
package com.example.projectquestion.reply;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ReplyRepository extends JpaRepository<Reply, Integer> {
}
ReplyService / ReplyServiceImpl.java
package com.example.projectquestion.reply;
import java.security.Principal;
public interface ReplyService {
void create(String rcontent, Integer bid, Principal principal);
}
package com.example.projectquestion.reply;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.projectquestion.board.Board;
import com.example.projectquestion.board.BoardRepository;
import com.example.projectquestion.customer.Customer;
import com.example.projectquestion.customer.CustomerRepository;
@Service
public class ReplyServiceImpl implements ReplyService {
@Autowired
private ReplyRepository replyRepository;
@Autowired
private CustomerRepository customerRepository;
@Autowired
private BoardRepository boardRepository;
@Override
public void create(String rcontent, Integer bid, Principal principal) {
Reply reply = new Reply(); // 새로운 answer 객체 생성
reply.setRcontent(rcontent); // 객체에 답변 내용 넣기
reply.setRdate(LocalDateTime.now()); //객체에 현재 날짜 시간 넣기
Optional<Board> tr = boardRepository.findById(bid);
reply.setRboard(tr.get());
Optional<Customer> tc = customerRepository.findByusername(principal.getName());
reply.setRauthor(tc.get()); //객체에 답변 작성자 정보 객체로 객체에 넣기
replyRepository.save(reply);// 최종 객체 저장
}
}
ReplyController.java
package com.example.projectquestion.reply;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/reply")
@Controller
public class ReplyController {
@Autowired
private ReplyService replyService;
@PostMapping("/create")
public String create(@RequestParam ("rcontent") String rcontent,
@RequestParam ("bid") Integer bid,
Principal principal) {
replyService.create(rcontent, bid, principal);
return "redirect:/board/readdetail/" + bid;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2> Read Detail </h2>
<a href="/board/readlist">List</a><br><br>
Id : [[${board.bid}]] <br>
Title : [[${board.btitle}]]<br>
Content : [[${board.bcontent}]]<br>
Username : [[${board.bauthor.username}]] <br>
Date : [[${board.bdate}]]<br>
<br><br>
<p><a th:href="@{|/board/update/${board.bid}|}"> update</a>
<p><a th:href="@{|/board/delete/${board.bid}|}"> delete</a>
<br>
<h4>Create Reply</h4>
<form action="/reply/create" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="hidden" name="bid" th:value="${board.bid}"/>
<p>Content : <input type="text" name="rcontent">
<input type="submit" value="create">
</form>
<h4>Replies List</h4>
There are [[${#lists.size(board.replyList)}]] Replies<br>
<div th:each="reply : ${board.replyList}">
[[${reply.rcontent}]] /
[[${#temporals.format(reply.rdate, 'yyyy-MM-dd HH:mm')}]] /
[[${reply.rauthor.username}]]
<br>
</div>
</body>
</html>
한국정보시스템개발원
|
Hankook Information System Institute
austiny@snu.ac.kr / austiny@gatech.edu