Cooper's devlog

4-5. 질문하기, 질문 목록 기능 구현 본문

Programming/Spring-boot

4-5. 질문하기, 질문 목록 기능 구현

cooper_dev 2020. 7. 20. 15:20

4-5. 질문하기, 질문 목록 기능 구현

1. 강의 링크

https://www.youtube.com/watch?v=aaC07qy3JXQ&list=PLqaSEyuwXkSppQAjwjXZgKkjWbFoUdNXC&index=28


2. 학습 목표

  • 로그인한 사용자에 대한 질문 가능하도록 구현
  • 질문 목록 기능 구현

 

 


3. 과정

  1. 질문 작성 기능 구현
  2. 목록 기능 구현하기

1. 질문 작성 기능 구현

[1]질문글 작성에 필요한 html 페이지 작성

(1) qna/form.html 작성

  • navigation : {{/include/navigation}} - mustache식으로 구현
  • footer : {{/include/footer}} - mustache식으로 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="kr">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>SLiPP Java Web Programming</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link href="../css/bootstrap.min.css" rel="stylesheet">
    <link href="../css/styles.css" rel="stylesheet">
</head>
<body>
 
{{>/include/navigation}}
 
<div class="container" id="main">
   <div class="col-md-12 col-sm-12 col-lg-10 col-lg-offset-1">
      <div class="panel panel-default content-main">
          <form name="question" method="post" action="/questions">
              <div class="form-group">
                  <label for="title">제목</label>
                  <input type="text" class="form-control" id="title" name="title" placeholder="제목"/>
              </div>
              <div class="form-group">
                  <label for="contents">내용</label>
                  <textarea name="contents" id="contents" rows="5" class="form-control"></textarea>
              </div>
              <button type="submit" class="btn btn-success clearfix pull-right">질문하기</button>
              <div class="clearfix" />
          </form>
        </div>
    </div>
</div>
 
{{>include/footer}}
 
    </body>
</html>
 

(2) Question(vo) 생성

  • jpa경우, mapping에서는 기본적으로 default 생성자가 필요하기 때문, default 생성자 생성 후 필드 생성자 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package net.slipp.domain;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
 
@Entity
public class Question {
    @Id
    @GeneratedValue
    private Long id;
    
    private String writer;
    
    private String title;
    
    private String contents;
 
    
    
    public Question() {
    }
 
    public Question(String writer, String title, String contents) {
        super();
        this.writer = writer;
        this.title = title;
        this.contents = contents;
    }
    
    
    
}
 
 

 

(3) questionController 작성 및 메소드 구현

  • form : '질문하기' 페이지 이동 메소드
  • create : 질문 내용 작성 기능 메소드
    • httpSession을 통한 작성자 식별 기능(if문)
    • 작성자는 일치하기 때문에 sessionedId의 값을 통해 작성자 등록
  • @autowired : 스프링 프레임워크에서 자동적으로 인자를 전달해주는 역할.
    • (미설정 시, NullPointException 발생)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package net.slipp.web;
 
import javax.servlet.http.HttpSession;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
import net.slipp.domain.Question;
import net.slipp.domain.QuestionRepository;
import net.slipp.domain.User;
 
@Controller
@RequestMapping("/questions")
public class QuestionController {
    
    @Autowired
    private QuestionRepository questionRepository;
    
    @GetMapping("/form")
    public String form(HttpSession session) {
        if(!HttpSessionUtils.isLoginUser(session)) {
            return "/users/loginForm";
        }
        return "qna/form";
    }
    
    @PostMapping()
    public String create(String title, String contents, HttpSession session) {
        if(!HttpSessionUtils.isLoginUser(session)) {
            return "/users/loginForm";
        }
        
        User sessionedUser = HttpSessionUtils.getUserFromSession(session);
        Question newQuestion = new Question(sessionedUser.getUserId(), title, contents);
        questionRepository.save(newQuestion);
        
        return "redirect:/";
    }
}
 
 

 

(4) QuestionRepository 구현

  • 작성 데이터를 db(H2)에 전달하기 위한 Repository interface 작성
  • JPARepository 상속받아서 구현하기
1
2
3
4
5
6
7
8
package net.slipp.domain;
 
import org.springframework.data.jpa.repository.JpaRepository;
 
public interface QuestionRepository extends JpaRepository<Question, Long>{
    
}
 
 

 

(5) index.html > href 수정

  • 작성한 메소드가 작동하도록 a href 수정

 

(6) 결과 확인

1_질문창에서 제목, 내용 입력

 

2_작성완료 내용 h2-db에서 확인

 

2. 목록 기능 구현

(1) HomeController 수정

  • h2 db에서 게시판 글을 모두 불러올 수 있도록 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package net.slipp.web;
 
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 net.slipp.domain.QuestionRepository;
 
@Controller
public class HomeController {
    @Autowired
    private QuestionRepository questionRepository;
    
    @GetMapping("")
    public String home(Model model) {
        model.addAttribute("questions", questionRepository.findAll());
        return "index";
    }
 
}
 
 

 

(2) index.html 수정

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <title>SLiPP Java Web Programming</title>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
        <link href="css/bootstrap.min.css" rel="stylesheet">
        <link href="css/styles.css" rel="stylesheet">
    </head>
    
<body>
 
{{>/include/navigation}}
 
<div class="container" id="main">
   <div class="col-md-12 col-sm-12 col-lg-10 col-lg-offset-1">
      <div class="panel panel-default qna-list">
          <ul class="list">
              {{#questions}}
              <li>
                  <div class="wrap">
                      <div class="main">
                          <strong class="subject">
                              <a href="./qna/show.html">{{title}}</a>
                          </strong>
                          <div class="auth-info">
                              <i class="icon-add-comment"></i>
                              <span class="time">2016-01-15 18:47</span>
                              <a href="./user/profile.html" class="author">{{writer}}</a>
                          </div>
                          <div class="reply" title="댓글">
                              <i class="icon-reply"></i>
                              <span class="point">8</span>
                          </div>
                      </div>
                  </div>
              </li>
              {{/questions}}
          </ul>
          <div class="row">
              <div class="col-md-3"></div>
              <div class="col-md-6 text-center">
                  <ul class="pagination center-block" style="display:inline-block;">
                      <li><a href="#">«</a></li>
                      <li><a href="#">1</a></li>
                      <li><a href="#">2</a></li>
                      <li><a href="#">3</a></li>
                      <li><a href="#">4</a></li>
                      <li><a href="#">5</a></li>
                      <li><a href="#">»</a></li>
                </ul>
              </div>
              <div class="col-md-3 qna-write">
                  <a href="/questions/form" class="btn btn-primary pull-right" role="button">질문하기</a>
              </div>
          </div>
        </div>
    </div>
</div>
 
{{>/include/footer}}
 
</body>
</html>
 

 

(3) 구현 내용 확인


 

Comments