class 32 - Spring Boot & ThymeLeaf

yoneeki·2023년 3월 20일
0

training-jp

목록 보기
22/31

스프링 톺아보기

(참고사이트)

  • Dispatcher Servlet : 스프링에 들어오는 모든 요청은 DispatcherServlet으로 들어온다
  • HandlerMapping : 그러면 DispatcherServlet이 해당 요청을 매핑한 컨트롤러가 있는지 검색한다
  • ViewResolver : Controller에서 보내온 view 이름을 토대로 처리 view를 검색 (prefix : /WEB-INF/.... jsp...)

스프링부트와 스프링 프레임워크

Spring Framework는 Java 개발을 위한 오픈 소스 애플리케이션 프레임워크입니다. 이 프레임워크는 대규모 엔터프라이즈급 애플리케이션을 만드는 데 사용됩니다. Spring Framework는 다양한 모듈로 구성되어 있으며, 이러한 모듈은 각각의 기능을 수행합니다.

Spring Boot는 Spring Framework를 기반으로하는 프레임워크입니다. Spring Boot는 스프링 애플리케이션을 보다 쉽게 개발하고 실행할 수 있도록 도와주는 도구입니다. Spring Boot는 애플리케이션을 더 빠르고 쉽게 시작할 수 있도록 기본 설정과 구성을 제공합니다. 또한 Spring Boot는 애플리케이션의 의존성을 관리하고 내장 서버를 제공하여 애플리케이션 배포를 간단하게 만듭니다.

즉, Spring Framework는 Java 애플리케이션을 개발하기 위한 프레임워크이고, Spring Boot는 Spring Framework를 기반으로하는 개발 도구이며, 스프링 애플리케이션을 보다 쉽게 개발하고 실행할 수 있도록 도와줍니다.

Spring Boot

Annotation & Container

  • 스프링은 Annotation을 전체적으로 스캔해서 그걸 Container (Object)에 올려놓는다.
  • 그래서 필요할 때마다 그것을 끄집어 낸다.
  • 작업을 할 때마다 그때 그때 객체를 생성하는 것이 아니다.

스프링 프레임워크의 핵심 기능 중 하나는 IoC(Inversion of Control, 제어의 역전) 컨테이너입니다. 이 컨테이너는 애플리케이션의 객체를 관리하고, 객체 간의 의존성을 해결하여 개발자가 객체 생성과 관리에 대한 부담을 덜어줍니다.

스프링에서는 컨테이너가 생성하고 관리하는 객체를 '스프링 빈(Spring Bean)'이라고 부릅니다. 스프링 빈은 일반적으로 자바 클래스로 구현되며, 스프링의 어노테이션을 사용하여 정의됩니다.

@Component 어노테이션은 스프링에서 빈으로 등록할 클래스에 붙이는 가장 기본적인 어노테이션입니다. @Controller, @Service, @Repository 등은 @Component 어노테이션을 확장한 것으로, 해당 클래스가 각각 컨트롤러, 서비스, 리포지토리 역할을 한다는 것을 명시적으로 표현합니다. 예를 들어, 다음과 같이 @Component 어노테이션을 사용하여 클래스를 스프링 빈으로 등록할 수 있습니다.

@Component
public class MyService {
    // 서비스의 기능을 구현한 코드
}

위 코드에서 @Component 어노테이션을 사용하여 MyService 클래스를 스프링 빈으로 등록하였습니다. 이제 MyService 클래스의 객체는 스프링 컨테이너에서 관리되고, 다른 빈에서 이 객체를 참조할 수 있습니다.

VSCode에 스프링 환경 만드는 경우

1.명령 팔레트
2.spring initializer maven project (Boot 환경)
3.버전 : 2.7.9 (스냅샷 x)
4.언어 : Java
5.메인 : ex) com.원하는이름 ~~
6.jar
7.java ver : 아무거나 필요한 거 (ex. 17)
8.dependencies : 필요한 거 추가 ex. web, devtools, lombok 등등...
9.pom.xml에 spring boot thymeleaf 2.7.9 ver 추가 (url 매핑 위해)
10.application.properties .... > server.port=9090 (서버 충돌 방지)
11.DemoApplication에서 main함수 run 돌려서 웹 실행되는지 확인

확장팩

  • java, spring pack
  • 롬복없는 경우 (ctrl + shift + p : generate getter setter.. constructor..)
  • 아니면 lombok extension 설치 (당연히 pom.xml에 디펜던시 추가도 해야 함)

lombok - slf4j

application 설정

application.properties

server.port=9090
spring.thymeleaf.check-template-location=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false

application.yaml

  • YAML : application.properties에 계속적으로 중복되는 부분을 효율적으로 작성하기 위하여 나왔으며 주석도 가능
# 어플리케이션 설정 : YAML 버전
server:
  port: 9090
spring:
  thymeleaf:
    check-template-location: true
    prefix: classpath:/templates/
    suffix: .html
    cache: false
# 포트 번호 변경
server:
  port: 9090


# 디버그 콘솔 색 넣기
spring:
  output:
    ansi:
      enabled: always

# 디버그 레벨 정하기
logging:
  level:
    '[com.jjang051.ch02]': DEBUG # ERROR로 바꾸면 ERROR 관련 사항만 뜬다

디버그 콘솔 설정

Slf4j


Spring initializr 로 개발환경 세팅

웹 실행

  • 어플리케이션에서 main 함수 실행 후 포트 문제 없이 접속이 잘 되고
  • index.html 파일이 없으면 이렇게 뜨는데
  • 일단 접속은 잘 된 상태

경로 & Controller & Mapping


  • templates 폴더 안의 html 파일의 이름이 GetMapping의 파라미터

@Controller

@Controller는 경로에 해당하는 파일을 찾는다

  • @Controller는 스프링 프레임워크에서 제공하는 어노테이션 중 하나로, 스프링 컨트롤러(Controller) 클래스임을 표시하는 역할을 합니다.
  • 스프링 MVC에서 컨트롤러는 클라이언트의 요청을 처리하고 응답을 반환하는 역할을 합니다. @Controller 어노테이션을 사용하여 해당 클래스를 스프링이 인식할 수 있도록 등록하면, 해당 클래스의 객체가 스프링 빈으로 생성되고, 스프링이 요청을 받았을 때 해당 컨트롤러의 메서드를 실행하여 요청을 처리하게 됩니다.
    예를 들어, 다음과 같이 @Controller 어노테이션을 사용하여 컨트롤러를 정의할 수 있습니다.
@Controller
public class HomeController {
    @GetMapping("/")
    public String home() {
        return "home";
    }
}
  • 위 코드에서 @Controller 어노테이션을 사용하여 HomeController 클래스를 컨트롤러로 등록하였고, home() 메서드는 @GetMapping("/") 어노테이션을 사용하여 "/" 경로에 대한 GET 요청을 처리합니다. home() 메서드는 "home" 문자열을 반환하며, 이는 뷰(View) 이름으로 사용되어 클라이언트에게 응답으로 전달됩니다.

@RestController

  • 바로 응답을 시켜버릴 수 있음 (현재 txt01이라는 파일을 새로 만들지 않았음)

JSON으로 보내기 - 직접 적기 (권장 X)

JSON으로 보내기 - HashMap

  • 스프링부트에서는 어떻게 GSON 라이브러리 없이 해시맵을 JSON으로 받는가?
  • maven dependency의 jackson

JSON으로 보내기 - DTO 클래스

JSO으로 보내기 - ArrayList & 제네릭

@ResponseBody

  /** Controller + ResponseBody = RestController */
  @GetMapping("/toJson01")
  @ResponseBody
  public String toJson() {
    return "Hello Json";
  }

  • 만약에 @RestController가 아닌 @Controller 등을 사용하는데도 파일을 찾는 대신 body로 리턴하고 싶으면 @ResponseBody를 사용한다.
  • 옛날에는 @RestController가 없어서 @Controller + @ResponseBody 로 사용했지만, 지금은 불가피한 경우가 아니면 @RestController 사용.

@RequestParam 어노테이션

@RequestParam은 스프링 프레임워크에서 제공하는 어노테이션 중 하나로, HTTP 요청에서 파라미터 값을 추출하기 위해 사용됩니다. 보통 HTTP 요청에서 파라미터는 URL 쿼리 스트링, 폼 데이터, HTTP 헤더 등을 통해 전달됩니다. @RequestParam 어노테이션을 사용하면 이러한 파라미터 값을 스프링 컨트롤러 메서드의 매개변수로 바로 주입받을 수 있습니다.

  • 변수명과 param명을 통일하지 않는 특수한 경우 (name= ... )
  • DTO를 쓰지 않았을 때와 DTO를 썼을 때
  • 사실 쿼리스트링이랑 변수끼리 이름만 맞으면 생략도 가능하다 (위의 경우처럼 통일되지 않는 경우는 제외)

Path Variable


@GetMapping("/info/{id}") //request mapping 있으니 member/info
  public String memberInfo(@PathVariable("id") String userId) {
    //이 경우는 @RequestParam이 아님
    // Restful한 경우 : url이 쿼리스트링이 아니라 sdfs.com/info/kim1234 이런 식으로 됨
    System.out.println(userId);
    return "/member/login";
  }
  • request param 대신에 path variable을 쓰는 경우
  • 쿼리스트링이 아닌 restful한 형식으로 url을 매핑할 때
  • EX. ~.com/info?id=kimkim // ~.com/info/kimkim

@Model 및 @ModelAndView

  • Model 객체를 훨씬 많이 쓰고 ModelAndView는 예전에 많이 쓰던 방식
  • Model 객체는 Request 객체와 비슷하다고 생각하면 편함 (서로 다르지만).
  • 왜냐하면 스프링의 model.addAttribute("name", value) 와 jsp 서블릿의 request.setAttribute("name", value)의 기능이 비슷하기 때문

redirect

ThymeLeaf (타임리프)

ThymeLeaf로 데이터 받기 1

  • vscode는 jsp를 지원해주지 않지만 thymeleaf를 지원한다.
  • 이클립스 jsp에서는 jstl로 request, response를 처리했지만 타임리프로도 동일한 기능을 수행할 수 있다.
  • html에 아래 이미지와 같이 작성하면 데이터를 수신받을 수 있다.

ThymeLeaf로 데이터 받기 2

  • 여러 방법으로 받을 수 있다
<!-- <input type="hidden" name="reGroup" value="${replyBoardDto.reGroup}" />
        <input type="hidden" name="reLevel" value="${replyBoardDto.reLevel}" />
        <input type="hidden" name="reStep" value="${replyBoardDto.reStep}" /> -->
        <input type="hidden" name="reGroup" th:value="${param.reGroup}" />
        <input type="hidden" name="reLevel" th:value="${param.reLevel}" />
        <input type="hidden" name="reStep" th:value="${param.reStep}" />

ThymeLeaf를 작성하는 두 가지 방법

ThymeLeaf 반복문 (w/ ArrayList)

Member DTO

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data // @Getter + @Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Member {

  private String id;
  private String name;
  private String addr;
}

HomeController

.
.
 @GetMapping("/member/list")
  public String list(Model model) {
    ArrayList<Member> memberList = new ArrayList<>();

    memberList.add(new Member("admin01", "운영자", "서울특별시 은평구"));
    memberList.add(new Member("alba01", "알바생", "서울특별시 중구"));
    memberList.add(new Member("customer01", "고객님", "서울특별시 송파구"));

    model.addAttribute("memberList", memberList);
    return "/member/list";
  }
.
.

list.html (..../member/list)

<!DOCTYPE html>
<html xmlns="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Member List</title>
    <style>
        .table {
            text-align: center;
        }
    </style>
</head>
<body>
    <h1> 고객 명단 </h1>
    <hr>
    <table class="table">
        <colgroup>
            <col width="100px" height="30px" style="background: #ffffff" />
            <col width="300px" height="30px" style="background: #eeeeee" />
            <col width="400px" height="30px" style="background: #999999" />
        </colgroup>
        <tr>
            <th>아이디</th>
            <th>이름</th>
            <th>주소</th>
        </tr>
 
        <tr th:each="member : ${memberList}">
            <td th:text="${member.id}"></td>
            <td th:text="${member.name}"></td>
            <td th:text="${member.addr}"></td>
        </tr>
    </table>
</body>
</html>

ThymeLeaf로 view include 기능

Thymeleaf Layout Dialect 라이브러리

  • 참고로 적용이 되지 않을 때는 버전 부분을 지우기

토대가 될 layout 작성

  • 적용이 가끔 안되는 경우가 있는데 확실하지는 않지만 난 저 lang="en" 부분을 의심 중임. 그래서 지우고 쓴다.

layout을 참고할 index를 작성

layout / index

profile
Working Abroad ...

0개의 댓글