관리 메뉴

A seeker after truth

스프링부트 책 4단원: mustache로 화면 구성 본문

Springboot

스프링부트 책 4단원: mustache로 화면 구성

dr.meteor 2020. 3. 21. 18:39

* 본문은 <스프링부트와 aws로 혼자 구현하는 웹서비스>(2019, 이동욱, 프리렉)을 공부하고 정리한 내용입니다. 코드에서 import 부분은 모두 생략했습니다.

 

그동안 조사 못했던 이것부터 알아보고 가자.

 

import static ~ 이란?

정적 메소드, 멤버 필드를 더 편하게 사용할 수 있는 방법이다.

정적 메소드는 호출할 때 클래스의 인스턴스 없이도 사용할 수 있는 메서드를 말한다.

이런 정적 메소드들을 import static ~ 선언문을 이용하면 클래스명 없이 바로 사용할 수 있다.

예시 코드를 보면 바로 이해할 수 있다.

출처: 

https://offbyone.tistory.com/283

https://xxxelppa.tistory.com/38

1
2
3
4
5
6
7
import static java.lang.System.*;
 
public class Example {
    public static void main(String[] ar) {
        out.println();
    }
}
cs

하지만 일반적으로 위 코드처럼 import 에 * 를 사용하는 것은 권장 되지 않는다.

 

 

1. 기본 페이지 만들기

본 코드에선 할게 딱히 없어서 테스트 코드에 있던 것중 모르는 것 메모. URL 호출 시 페이지 내용이 제대로 호출되는지에 대한 테스트다.

html도 결국 규칙이 있는 문자열이라, TestRestTemplate을 통해 "/"로 호출했을 때 index.mustache 에 포함된 코드들이 있는지 확인하면 된다. 전체 코드를 다 검증할 필요는 없기 때문에 "스프링 부트로 시작하는 웹 서비스"가 포함되어 있는지만 비교한다.

TestRestTemplate 클래스의 getForObject 메서드

   - Retrieve a representation by doing a GET on the URI template.

출처:

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/web/client/TestRestTemplate.html

 

 

2. 게시글 등록 화면 만들기

1) 프론트엔드 라이브러리를 사용할 수 있는 방법

첫째, 외부 CDN(Contents Delivery Network) 사용

*CDN이란? 음원, 영상 등 10메가 이상의 대용량 파일을 병목 현상 없이 안정적으로 제공하는 기술. 네트워크 트래픽 자체를 줄여주는 기술. 더 자세한 내용은 아래 링크. 

https://goddaehee.tistory.com/173

*실제 서비스엔 외부 서비스에 자사 서비스가 의존하게 되기 때문에 이 방법을 잘 사용하지 않는다.

둘째, 직접 라이브러리를 받아서 사용.

여기선 전자의 방법 사용.

그리고 레이아웃 방식을 사용할건데, 레이아웃 방식이란 공통 영역을 별도의 파일로 분리하여 필요한 곳에서 가져다 쓰는 방식.

 

2) header, footer mustache

페이지 로딩 속도를 높이기 위해 css는 header, js는 footer에 둠

    •HTML은 head가 다 실행되고 나서 body가 실행됨->css는 화면을 그리는 역할이므로 head에서 불러오고, 이게 다 실행되고 나서 (무거워 질 수 있는) js를 body에서 불러오게 함

    •head가 다 불러지지 않으면 사용자 쪽에선 백지 화면만 노출됨

    •head 속 css가 다 불러지지 않으면 이게 적용되지 않은 깨진 화면 노출

    •js 용량이 클수록 body 실행이 늦어짐

•bootstrap.js는 jQuery가 꼭 있어야만 함(부트스트랩의 제이쿼리 의존성)->부트스트랩보다 제이쿼리가 먼저 호출되게 코드 작성

•{{> }}는 현재 머스테치 파일인 index.mustache 기준으로 다른 파일을 가져온다

•<a>태그로 글 등록 페이지로 이동하는 글 등록 버튼 생성

 

3) index.js

142~3의 스코프, var init어쩌고 하는 부분. 난 자스를 몰라서 나중에 한번 더 봐야할 내용.

 

4) PostsRepository 인터페이스에 쿼리 추가

public interface PostsRepository extends JpaRepository<Posts, Long> {
    @Query("SELECT p FROM Posts p ORDER BY p.id DESC")
    List<Posts> findAllDesc();
}

위 코드는 SpringDataJpa에서 제공하는 기본 메서드만으로도 해결 가능한데, 위처럼 @Query로 작성해도 됨. 가독성은 @쿼리가 훨 좋다.

*Querydsl 추천에 대한 이야기는 147쪽, 시간관계상 메모 생략

 

5) PostsListResponseDto 생성

 

6) PostsService 에 findAllDesc() 메서드 추가

@Transactional(readOnly = true)
    public List<PostsListResponseDto> findAllDesc() {
        return postsRepository.findAllDesc().stream()
                .map(PostsListResponseDto::new)
                .collect(Collectors.toList());
    }

readOnly 옵션은 CRUD 기능이 전혀 없는 서비스 메서드에서 사용하면 좋다. 트랜잭션 범위는 유지하되 조회 기능만 남겨두어 조회속도가 개선된다. 문서 등을 '읽기 모드'할 떄를 생각해보면 상식적으로 이해 가능.

.map(PostsListResponseDto::new) 은 .map(posts->new PostsListResponseDto(posts))와 동치(람다식)다. 왜 posts지..?

postsRepository 결과로 넘어온 posts의 stream을 맵을 통해 PostsListResponseDto 변환->Lists로 반환하는 메서드다.

 

 

 

 

[html 문법 검색해보기]

<label for="~">: 사용자 인터페이스(UI) 요소의 라벨을 정의할 때 사용한다. for 속성을 통해 다른 요소와 결합할 수 있다. 그냥 봐선 이해 안되므로 아래 링크를 통해 예시 코드 및 실행 결과와 함께 이해할 것

http://tcpschool.com/html-tags/label