질문 등록

prana·2023년 5월 25일

SpringBoot

목록 보기
15/22
post-thumbnail

질문 등록하기 버튼 추가

<!DOCTYPE html>
<html layout:decorate="~{layout}" xmlns:layout="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div layout:fragment="content" class="container my-3">
<table class="table">
    <thead class="table-dark">
    <tr>
        <th>번호</th>
        <th>제목</th>
        <th>작성일시</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="question, loop : ${questionList}">
        <td th:text="${loop.count}"></td>
        <td>
            <a th:href="@{|detail/${question.id}|}" th:text="${question.subject}"></a>
        </td>
        <td th:text="${#temporals.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></td>
    </tr>
    </tbody>
</table>
    <a th:href="@{/question/create}" class="btn btn-primary">질문 등록하기</a>
</div>
</body>
</html>

a링크를 타고 들어갈 때는 getmapping이니까 컨트롤러에
내용을 추가해주고,

//QuestionController.java
  @GetMapping("/create")
    public String questionCreate() {
        return "question_form"; // 질문 저장후 질문목록으로 이동
    }
    

이 폼 화면을 a링크 타고 들어갈 때 화면이 나올 수 있도록 한다.

question_form.html

<html layout:decorate="~{layout}" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:layout="http://www.w3.org/1999/xhtml">
<div layout:fragment="content" class="container">
    <h5 class="my-3 border-bottom pb-2">질문등록</h5>
    <form th:action="@{/question/create}" ✅method="post">
        <div class="mb-3">
            <label for="subject" class="form-label">제목</label>
            <input type="text" name="subject" id="subject" class="form-control">
        </div>
        <div class="mb-3">
            <label for="content" class="form-label">내용</label>
            <textarea name="content" id="content" class="form-control" rows="10"></textarea>
        </div>
        <input type="submit" value="저장하기" class="btn btn-primary my-2">
    </form>
</div>
</html>

저장하기 버튼을 누르게 되면 method 방식이 post이므로, 컨트롤러에 get 방식이 아닌 post방식으로도 하나 더 추가해준다.
폼에 글을 쓰면 화면에 보이다시피 제목과 내용을 담아서 전달해주어야 한다.

 @GetMapping("/create")
    public String questionCreate() {
        return "question_form"; // 질문 저장후 질문목록으로 이동
    }
👉 차이점이 있다면 목록 화면에서 a링크 타고 넘어올 땐 get, 
질문 등록 폼에 내용을 담아서 보낼 때는 (html에 post 방식이었기에) PostMapping으로 연결해준다. 

💡 메서드명이 같아도 매개변수의 형태 다를 경우에 사용하는 메서드 오버로딩

 @PostMapping("/create")
    public String questionCreate(@RequestParam String subject, @RequestParam String content){
        // TODO: 질문을 저장한다.
        return "redirect:/question/list"; //질문 저장 후 질문 목록으로 이동
    }

QuestionService.java

 public void create(String subject, String content) {
        Question q = new Question();
        q.setSubject(subject);
        q.setContent(content);
        q.setCreateDate(LocalDateTime.now());
        this.questionRepository.save(q);
    }

해당 기능을 만들어준다.

컨트롤러에 서비스 넣어주기

   @PostMapping("/create")
    public String questionCreate(@RequestParam String subject, @RequestParam String content){
        // TODO: 질문을 저장한다.
       👉 this.questionService.create(subject, content);
        return "redirect:/question/list"; //질문 저장 후 질문 목록으로 이동
    }




빈 값으로 등록 못하게 하기

//build.gradle
dependencies {
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.projectlombok:lombok:1.18.26'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.h2database:h2'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
	✅ implementation 'org.springframework.boot:spring-boot-starter-validation'

}


출처 : https://wikidocs.net/161873

QuestionForm.java

package com.mysite.sbb.question;

import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class QuestionForm {
    @NotEmpty(message="제목은 필수항목입니다.")
    @Size(max=200)
    private String subject;

    @NotEmpty(message="내용은 필수항목입니다.")
    private String content;
}

@NotEmpty, @Size

빈값 막기, 최대 길이를 확인하기 위해서는 질문 폼 클래스가 필요하다.

✅ @Size(max=200)은 최대 길이가 200 바이트를 넘으면 안된다는 의미이다.

폼 미쳤다

QuestionController.java

 @PostMapping("/create")
    public String questionCreate(👉@Valid QuestionForm questionForm, BindingResult bindingResult){
        // TODO: 질문을 저장한다.
        if (bindingResult.hasErrors()) {
            return "question_form";
        }
        this.questionService.create(questionForm.getSubject(), questionForm.getContent());
        return "redirect:/question/list"; //질문 저장 후 질문 목록으로 이동
    }

기존에 @RequestParam String subject, @RequestParam String content 받던 것을
👉@Valid QuestionForm questionForm, BindingResult bindingResult 로 변경했다.

subject, content 항목을 지닌 폼이 전송되면 QuestionForm 의 subject, content 속성이 자동으로 바인됭 된다.

  • @Valid 애너테이션을 적용하면 @NotEmpty, @Size 등 설정한 검증 기능이 동작한다.

0개의 댓글