사이먼's 코딩노트

[SpringBoot] Answer 저장 및 출력 / 스타일시트 적용 본문

Java/SpringBoot

[SpringBoot] Answer 저장 및 출력 / 스타일시트 적용

simonpark817 2024. 5. 9. 15:16

[Answer 저장 및 출력]

  • 답변을 저장하는 기능을 추가하기 위해 AnswerService.java 를 도입해봅시다.
  • 먼저 AnswerController.java 클래스에서 question_detail.html 템플릿을 통해 작성된 textarea의 content를 서비스로 보내주는 코드를 작성해야 한다.
  • 아래는 AnswerController.java 클래스에 추가 작성된 코드이다.
package com.sbs.sbb.Answer;

import com.sbs.sbb.Question.Question;
import com.sbs.sbb.Question.QuestionRepository;
import com.sbs.sbb.Question.QuestionService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@RequestMapping("/answer")          
@Controller
@RequiredArgsConstructor           
public class AnswerController {
    private final QuestionService questionService;
    private final AnswerService answerService;

    @PostMapping("/create/{id}")
    public String createAnswer(Model model, @PathVariable("id") Integer id, @RequestParam(value="content") String content) {
        Question q = this.questionService.getQuestion(id);
        
        Answer answer = this.answerService.create(q, content);

        return "redirect:/question/detail/%d".formatted(id);
    }
}
  • 클래스 안에 private final AnswerService answerService; 코드를 추가하고, @RequiredArgsConstructor 어노테이션이 적용되어있기 때문에 자동으로 객체가 생성된다.
  • createAnswer() 메서드 안에서 Answer answer = this.answerService.create(q, content); 코드를 추가하여 서비스를 통해 create() 메서드를 호출한다. 이 때 q는 id 번호에 따른 question 데이터이고, content는 textarea에 작성한 답변 내용을 의미한다.

 

[Answer 데이터 저장]

  • 아래는 AnswerService.java 클래스를 생성하여 작성한 답변을 저장하도록 추가 작성된 코드이다.
package com.sbs.sbb.Answer;

import com.sbs.sbb.Question.Question;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@RequiredArgsConstructor
@Service
public class AnswerService {
    private final AnswerRepository answerRepository;

    public Answer create(Question q, String content) {
        Answer answer = new Answer();
        answer.setContent(content);
        answer.setQuestion(q);
        answer.setCreateDate(LocalDateTime.now());
        this.answerRepository.save(answer);

        return answer;
    }
}
  • AnswerService.java 클래스에서 answer 데이터 하나를 생성하기 위해 create() 메서드를 추가하였다.
  • create() 메서드는 입력받은 2개의 매개변수인 q와 content를 사용하여 Answer 객체를 생성하여 저장하였고, 마지막에 answerRepository를 통해 해당 데이터를 save() 하였다.

 

[Answer 데이터 출력]

  • 저장하는 기능이 구현되었다면 실제로 화면에 출력하기 위해 템플릿 수정이 필요하다.
  • 아래는 각 질문 아래에 답변이 보이도록 상세 내용 페이지 템플릿인 question_detail.html에 추가된 코드이다.
<h2>
    <h3 th:text="${question.id}"></h3>
    <div th:text="${question.subject}"></div>
    <div th:text="${question.content}"></div>
</h2>

<h5 th:text="|${#lists.size(question.answerList)}개의 답변이 있습니다.|"></h5>
<div>
    <ul>
        <li th:each="answer : ${question.answerList}" th:text="${answer.content}"></li>
    </ul>
</div>

<!--입력 폼 만들기-->
<form th:action="@{|/answer/create/${question.id}|}" method="POST">
    <div>
        <span>내용</span>
        <br>
        <textarea name="content" placeholder="내용" rows="5"></textarea>
    </div>

    <button type="submit">답변등록</button>
</form>
  • 템플릿의 중간 부분에 답변을 확인할 수 있는 영역을 추가하였다.
  • #lists.sitze(question.answerList)는 답변의 총 개수를 의미하고 실제 화면에서는 "~개의 답변이 있습니다." 라고 출력하게 되고, 그 안에 each 반복문을 사용하여 모든 답변의 내용을 출력하게 된다.
  • 다시 로컬 서버를 실행하여 2번 question의 상세 내용 페이지인 localhost:8090/question/detail/2로 접속하게 되면 아래와 같이 답변 내용도 함께 출력된다.

템플릿에 추가된 답변 목록

 

[스타일시트 적용]

  • 지금부터는 각 템플릿을 디자인하기 위해 스타일시트인 CSS를 사용해봅시다.
  • 먼저 세부적인 디자인을 시작하기 전에 스타일시트 파일인 style.css를 생성해봅시다. 템플릿의 경우, templates 디렉터리 아래에 파일들을 추가하였지만 CSS는 static이라는 디렉터리를 새로 생성하여 그 아래에 style.css를 생성한다.
  • 아래는 새로 추가된 style.css에 작성된 코드이다.
textarea {
    width:100%;
}

input[type=submit] {
margin-top:10px;
}
  • style.css에 작성된 코드의 내용은 답변 등록을 위한 form 태그의 textarea 속성인 입력하는 부분의 너비를 100%로 맞추고, input 속성으로 구성된 버튼의 상위 여백을 10px로 지정하였다.
  • 이렇게 스타일시트를 따로 작성했다고 해서 바로 템플릿에 적용되는 것은 아니다.
  • 아래는 작성한 스타일시트 파일을 question_detail.html 템플릿에 적용한 코드이다.
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
  • 템플릿의 가장 상단에 위와 같은 코드를 추가하면 되고, 여기서 주의해야 할 점은실제로 style.css 파일이 static 디렉터리 아래에 위치하지만 링크 경로를 /static/style.css이 아닌 /style.css로 작성한다.
  • 그 이유는 static 디렉터리가 스태틱 파일들의 루트 디렉터리이므로 적을 필요가 없기 때문이다.
  • 다시 로컬 서버를 실행항여 2번 question의 상세 내용 페이지인 localhost:8090/question/detail/2로 접속하게 되면 아래와 같이 기본 스타일시트가 적용된 모습을 볼 수 있다.

스타일시트가 적용된 question_detail.html

 

 

반응형