Spring의 WebFlux+Thymeleaf로 화면 보기

개요



3 월 모일 회사에서
  • 직장에서 프로토 타입을 만들 때 많은 양의 데이터를 한 번에 볼 수있는 사안이 있습니다.
  • 원한다면 소문의 WebFlux를 이용해 보자
  • Thymeleaf에서 보자

  • 라고 하는 것으로, 조사했을 때의 정리입니다.
    WebFlux는 이것을 나중에 요약하고 싶습니다 (여기의 설명에서는 생략합니다)

    여담



    Spring Boot 2.0 goes GA
    마침내 Spring Boot가 정식 버전으로 공개되었습니다.
    이용이 가속되어 문서가 늘어나면 기쁘네요(`・ω・´)

    Spring Initializr 또한 데포가 2.0.0입니다.

    개발



    필요한 설정과 코드를 작성합니다.
    WebFlux+Thymeleaf에서 동작 확인을 위한 최소 구성입니다.

    dependencies



    (당연합니다만) Spring Boot2계가 필요
  • spring-boot-starter-webflux
  • spring-boot-starter-thymeleaf

  • pom.xml
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-webflux</artifactId>
            </dependency>
        <dependencies>
    
    

    컨트롤러



    평소 thymeleaf에서 사용하는 템플릿의 이름을 반환하는 프로세스에 Flux를 템플릿에 전달하는 프로세스를 추가합시다.
    Flux에 대해서는 이쪽 -> 23. WebFlux framework

    WebController.java
    
    @Controller
    @RequestMapping("/test")
    public class WebController {
    
        @GetMapping
        public String index(Model model) {
            Flux<String> flux = Flux
                    .range(0, 5)
                    .map(i -> "count :" + i)
                    .repeat(10)
                    .delayElements(Duration.ofSeconds(1L));
    
            model.addAttribute("items", new ReactiveDataDriverContextVariable(flux, 1));
    
            return "index";
        }
    }
    

    위의 Flux 인스턴스 처리 설명


    방법
    개요


    범위
    0에서 4까지 증가하여 출력하는 Flux 생성


    count : 0 와 같은 캐릭터 라인을 출력하는 Flux를 돌려준다

    repeat
    상기 Flux를 10회 반복

    delayElements
    Flux의 출력마다 delay 설정



    위 코드에서하는 일은 다음과 같습니다.
    1. Flux의 인스턴스 생성
    2. 생성된 인스턴스를 ReactiveDataDriverContextVariable 로 wrap하여 Model에 전달

    ReactiveDataDriverContextVariable



    새로운 Thymeleaf 클래스org.thymeleaf.spring5.context.webflux.ReactiveDataDriverContextVariable;
    이 클래스에서 Flux 인스턴스를 wrap 해 org.springframework.ui.Model 에 add 하는 것만으로 Data-Driven 모드로서 동작한다.
    결과적으로, 서버 측에서 비동기 적으로 출력 된 데이터는 SSE (Server Sent Event)에 의해 순차적으로 표시 측으로 송신된다.
    (코코라엔 분위기적인 이해도이므로, 이해가 진행되면 추기해 갑니다.)

    template



    여기는 Model에 List 인스턴스가 건네졌을 때와 같이 써 두면 OK입니다.
    특별한 설명은 필요하지 않습니다.
    <html xmlns:th="http://www.w3.org/1999/xhtml">
    <head>
    </head>
    <body>
    <h1>FluxTest</h1>
    <table>
        <thead>
        <tr>
            <th>title</th>
        </tr>
        </thead>
    
        <tbody>
        <tr th:each="item : ${items}">
            <td>[[${item}]]</td>
        </tr>
        </tbody>
    </table>
    </body>
    </html>
    

    데모




    ※처음에 몇개인가 표시되어 버리고 있는 것은, 그냥의 녹화 미스입니다(´;ω;`)부랏
    이것으로 첫 WebFlux + Thymeleaf가 가능했습니다!

    조사중에 빠진 곳



    원래 프로토타입 작성 초기는 Spring Boot 1계를 이용하고 있었을 때에
    WebFlux를 이용해 보려고 적당히 의존을 추가하고 코드를 고치면 아래와 같은 표시가 되어 있었다.



    curl 커맨드 등으로 content-type: text/event-stream 몇 시간…
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-webflux</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    

    spring-boot-starter-web과 함께 종속성에 추가했기 때문에
    Thymeleaf가 이전까지의 해석으로 템플리를 생성하고 있었던 것이 아닐까.

    통상의 API등은 양쪽 의존관계에 존재해도 문제 없게 동작했습니다/(^o^)\

    요약


  • Spring-Boot2가 공식적으로 출시되었습니다
  • 사용할 기회가 있거나 없을 수도 있지만 입문 할 때 도움이되면
  • spring-boot-starter-webfluxspring-boot-starter-web가 함께 정의되면 Thymeleaf가 제대로 작동하지 않습니다

  • SpringFramework5계 + SpringBoot2계를 캐치업 해 두지 않으면(^o^

    참고


  • danielfernandez/reactive-matchday
  • Spring I / O 2017 보고서 Thymeleaf WebFlux 지원
  • 좋은 웹페이지 즐겨찾기