본문 바로가기
Spring

2022-09-27 스프링(질문 목록 및 템플릿 / Root URL)

by allwing12 2022. 9. 27.
<h2>Hello Template!!!</h2>

 

위 처럼 resources 에 templates 에 다가 html 파일을 하나 만들었다.

리액트를 사용하지 않고 스프링부트로 간단하게 html을 진행하려고 한다.

 

 

 

그리고 build.gradle에 위의 내용을 추가 해서 타임리프 라는 것을 설치를 한다.

그리고 위의 HTML 내용 처럼 h2 태그 안에 Hello Template 라는 것을 작성하고

로컬 서버를 실행하고 해당 로컬 서버에 들어가면 된다.

근데 그 전에

 

 

 

이런 해당 컨트롤러를 만들어야하며 로컬서버는 당연히 localhost:포트번호/question/list 로 들어가면 된다.

 

 

package com.mysite.sbb.question;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class QuestionController {

    @RequestMapping("/question/list")
   // @ResponseBody
    public String list() {
        return "question_list";
    }
}

 

근데 위의 내용을 추가하게 된다면 ResponseBody를 쓰지 않아도 된다.

이렇게 한 후 로컬서버에 들어가게 되면 Hello Template가 보이게 될거다.

그렇다면 이제 여기에서 질문 리스트를 직접 보이게 만들거다.

 

 

package com.mysite.sbb.question.Controller;

import com.mysite.sbb.question.dao.QuestionRepository;
import com.mysite.sbb.question.domain.Question;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class QuestionController {

    private final QuestionRepository questionRepository;

    @RequestMapping("/question/list")
    public String list(Model model) {
        List<Question> questionList = questionRepository.findAll();
        model.addAttribute("questionList", questionList);
        return "question_list";
    }
}

 

QuestionController의 내용을 추가를 했다.

return "question_list" 위에 List에 대한 내용들을 추가를 했으며

List와 model에 대한 부분을 import를 했다

그 전에 우선적으로 @RequiredArgsConstructor 애너테이션을 추가를 했다.

questionRepository 속성을 포함하는 생성자를 생성한 것과 같다.

 

@RequiredArgsConstructor는 롬복이 제공하는 애너테이션으로 final이 붙은 속성을 포함하는

생성자를 자동으로 생성하는 역할을 한다고 한다.

롬복의 Getter와 Setter가 자동으로 Getter와 Setter 메서드를 생성하는 것과 마찬가지로 

@RequiredArgsConstructor는 자동으로 생성자를 생성한다고 한다.

 

스프링에는 의존성 주입 규칙이 있다고 하는데 방식 3가지가 있다고 한다.

 

 

위와 같이 있다고 하니 참고를 하자.

위으 코드는 Question 리포지터의 findAll 메서드를 사용해서 질문 목록 데이터인

questionList를 생성하고 Model 객체에 "questionList"라는 이름으로 값을 저장했고

Model 객체는 자바 클래스와 템플릿 간의 연결고리 역할을 한다고 한다.

Model 객체에 값을 담아두면 템플릿에서 그 값을 사용할 수 있다고 한다.

 

 

그리고 이렇게 HTML 구조를 작성했다.

여기에서 th:each="question : ${questionList}" 는 처음 본 표현인데

th: 로 시작하는 속성은 타임리프 템플릿 엔진이 사용하는 속성이라고 한다.

이 부분이 자바 코드와 연결된다고 한다.

 

자 여기에서 이제 자바의 for-each문을 생각하면 쉽게 이해할 수 있는 내용이 나오게 되는데

우선 QuestionController의 list 메서드에서 조회한 질문 목록 데이터를 "questionList" 라는 이름으로

Model 객체에다가 저장을 했다, 타임리프는 Model 객체에 저장된 값을 읽을 수 있으므로

템플릿에서 questionList를 사용할 수 있게 되는 것이라고 한다.

위의 HTML 코드는 <tr>...</tr> 엘리먼트를 questionList 의 갯수만큼 반복하여 출력하는 역할을 한다고 한다.

 

그리고 questionList에 저장된 데이터를 하나씩 꺼내 question 객체에 대입하여 반복구간 내에서 사용할 수 있게 하며

이게 바로 자바의 for-each 문과 비슷한 내용이라고 한다.

 

<td th:text="${question.subject}"></td>

<td th:text="${question.createDate}"></td>

 

이 코드는 바로 앞의 for문에서 얻은 question 객체의 제목을 <td> 엘리먼트의 텍스트로 출력한다고 한다.

그리고 그 밑의 코드도 위의 코드와 같은 맥락이라고 한다.

이렇게 해서 위의 HTML 코드 처럼 작성을 하고 로컬 서버에 들어가게 된다면

 

 

 

위의 화면처럼 보이게 된다.

그리고 그 밑에 자주 사용하는 타임리프의 속성을 알아보려고 하는데

타임리프의 자주 사용하는 속성에는 3가지 유형이 있다고 하며 이 3가지 유형만 알아도

여러가지 기능을 충분히 만들 수 있다고 하니 숙지하는게 좋을 듯 하다.

 


th:if="${question != null}"

 

위의 코드는 타임리프 속성 중 분기문 속성이라고 하는데 위의 코드와 같이 사용을 한다.

위의 경우에는 question 객체가 null 이 아닌 겨웅에 해당 엘리먼트가 보인다고 한다.

 

 

th:each="question : ${questionList}"

th:each="question, loop : ${questionList}"

 

반복문 속성으로 반복횟수만큼 해당 엘리먼트를 반복해서 표시하며 반복문 속성은 자바의 for each 문과 비슷하다.

그리고 코드가 두개인데 밑의 코드처럼도 사용을 할 수 있으며 추가한 loop 객체를 이요해서

루프 내에서 밑의 내용과 같은 속성을 사용할 수 있다고 한다.

 

  • loop.index - 반복 순서, 0부터 1씩 증가
  • loop.count - 반복 순서, 1부터 1씩 증가
  • loop.size - 반복 객체의 요소 갯수 (예: questionList의 요소 갯수)
  • loop.first - 루프의 첫번째 순서인 경우 true
  • loop.last - 루프의 마지막 순서인 경우 true
  • loop.odd - 루프의 홀수번째 순서인 경우 true
  • loop.even - 루프의 짝수번째 순서인 경우 true
  • loop.current - 현재 대입된 객체 (예: 위의 경우 question과 동일)

 

이런 속성들을 사용할 수 있다고 하니 참고 하자!

 

th:text="${question.subject}"


<tr th:each="question : ${questionList}">
    <td>[[${question.subject}]]</td>
    <td>[[${question.createDate}]]</td>
</tr>

 

위의 코드는 텍스트 속성으로 th:text=값 으로 사용하며 엘리먼트의 텍스트로 "값"을 출력한다고 한다.

텍스트는 th:text 속성 대신에 그 아래 코드처럼 대괄호를 사용해서 값을 직접 출력할 수 있다고 한다.

 

 


그 다음은 우리가 일반적으로 매핑을 한 URL로 도메인에 들어갈 수 있다.

예를 들어서

@RequestMapping("/question/list")

 

이런 코드를 통해서 URL을 매핑을 해서 로컬서버에 question/list 를 입력해야지 들어갈 수 있다.

근데 이 것을 없애는는 방법으로 Root URL 이라고 한다.

 

@RequestMapping("/")
public String root() {
    return "redirect:/question/list";
}

 

MainController 에 위의 코드를 입력을 하면 "/" << url을 매핑을 한것과 같다.

리턴 문자열 redirect:/qustion/list는 /question/list URL로 페이지를 리다이렉트 하라는 명령어라고 한다.

스프링부트에서 리다이렉트 또는 포워딩을 다음과 같이 할 수 있다고 한다.

 

  • redirect:<URL> - URL로 리다이렉트 (리다이렉트는 완전히 새로운 URL로 요청이 된다.)
  • forward:<URL> - URL로 포워드 (포워드는 기존 요청 값들이 유지된 상태로 URL이 전환된다.)

 

그리고 이렇게 한 후에 localhost:설정한포트번호 로 들어가면 root 메서드가 실행이 되어

우리가 했던 질문 목록이 화면에 나오는 것을 확인할 수 있다.

근데 해보니까 localhost:포트번호를 해서 들어가면 들어가지는데 자동적으로 URL이

localhost:포트번호/question/list 로 들어가진다.

 

댓글