1.9. View Technologies

편집일시: 2021-04-12 16:03 조회수: 268 댓글수: 0
[Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view) Spring WebFlux에서 뷰 기술의 사용은 플러그 가능한다. Thymeleaf, FreeMarker 또는 기타 표시 기술을 사용할지 여부는 주로 구성 변경의 문제이다. 이 장에서는 Spring WebFlux와 통합된 뷰 기술에 대해 설명한다. 이미 [View Resolution](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-viewresolution)에 대해 잘 알고 있다는 것을 전제로 하고 있다. ## 1.9.1. Thymeleaf [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-thymeleaf) Thymeleaf은 더블 클릭으로 브라우저에서 미리 볼 수 있는 자연스러운(natural) HTML 템플릿을 강조하는 최신 서버 측 Java 템플릿 엔진이다. 이것은 UI 템플릿(디자이너 등)에서 별도의 작업이 필요없이 매우 도움이 된다. 실행중인 서버. Thymeleaf는 광범위한 기능 세트를 제공하고 적극적으로 개발 및 유지 보수되어 있다. 완전한 소개 내용은 [Thymeleaf](https://www.thymeleaf.org/) 프로젝트의 홈페이지를 참조해라. Thymeleaf와 Spring 통합 WebFlux는 Thymeleaf 프로젝트에 의해 관리된다. 구성은 `SpringResourceTemplateResolver`, `SpringWebFluxTemplateEngine`, `ThymeleafReactiveViewResolver`등의 일부 Bean 선언이 포함되어 있다. 자세한 내용은 [Thymeleaf+Spring](https://www.thymeleaf.org/documentation.html)와 WebFlux 통합 [발표](http://forum.thymeleaf.org/Thymeleaf-3-0-8-JUST-PUBLISHED-td4030687.html)을 참조해라. ## 1.9.2. FreeMarker [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-freemarker) [Apache FreeMarker](https://freemarker.apache.org/)는 HTML에서 메일 등의 모든 종류의 텍스트 출력을 생성하기 위한 템플릿 엔진이다. Spring Framework는 Spring WebFlux와 FreeMarker 템플릿을 사용하는 기본 통합 기능이 있다. ### 뷰 설정(View Configuration) [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-view) 다음의 예제는 FreeMarker를 뷰 기술로 설정하는 방법을 보여준다. Java ``` @Configuration @EnableWebFlux public class WebConfig implements WebFluxConfigurer { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.freeMarker(); } // Configure FreeMarker... @Bean public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("classpath:/templates/freemarker"); return configurer; } } ``` Kotlin ``` @Configuration @EnableWebFlux class WebConfig : WebFluxConfigurer { override fun configureViewResolvers(registry: ViewResolverRegistry) { registry.freeMarker() } // Configure FreeMarker... @Bean fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply { setTemplateLoaderPath("classpath:/templates/freemarker") } } ``` 템플릿은 이전 예제에 표시된 `FreeMarkerConfigurer`로 지정된 디렉토리에 저장해야 한다. 위의 구성에서 컨트롤러가 뷰 이름 `welcome`을 반환하는 경우, 리졸버는 `classpath:/templates/freemarker/welcome.ftl` 템플릿을 찾는다. ### FreeMarker 설정 [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-views-freemarker) `FreeMarkerConfigurer` Bean에서 적절한 Bean 프로퍼티를 설정함으로써 FreeMarker의 "설정"과 "SharedVariables"를 FreeMarker `Configuration` 객체(Spring에 의해 관리됨)에 직접 전달할 수 있다. `freemarkerSettings` 속성은 `java.util.Properties` 객체가 필요하고, `freemarkerVariables` 속성을 `java.util.Map`해야 한다. 다음 예제는 `FreeMarkerConfigurer` 사용 방법을 보여준다. Java ``` @Configuration @EnableWebFlux public class WebConfig implements WebFluxConfigurer { // ... @Bean public FreeMarkerConfigurer freeMarkerConfigurer() { Map<String, Object> variables = new HashMap<>(); variables.put("xml_escape", new XmlEscape()); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("classpath:/templates"); configurer.setFreemarkerVariables(variables); return configurer; } } ``` Kotlin ``` @Configuration @EnableWebFlux class WebConfig : WebFluxConfigurer { // ... @Bean fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply { setTemplateLoaderPath("classpath:/templates") setFreemarkerVariables(mapOf("xml_escape" to XmlEscape())) } } ``` `Configuration` 객체에 적용되는 설정 및 변수에 대한 자세한 내용은 FreeMarker 문서를 참조해라. ### 폼 처리(Form Handling) [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-freemarker-forms) Spring은 특히 `<spring:bind/>` 요소가 포함된 JSP에서 사용하는 태그 라이브러리를 제공한다. 이 요소는 양식은 주로 양식 뒷면 객체의 값을 표시하여 Web 또는 비즈니스 계층의 `Validator`에서 검증 실패의 결과를 볼 수 있다. Spring은 FreeMarker와 같은 기능을 지원하고 있지만, 폼 입력 요소 자체를 생성하기 위한 추가의 편리한 매크로가 있다. ### 바인딩 매크로(The Bind Macros) [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-bind-macros) 매크로의 표준 세트는 FreeMarker의 `spring-webflux.jar` 파일에서 유지되기 때문에, 적절하게 구성된 응용 프로그램에서 항상 사용할 수 있다. Spring 템플릿 라이브러리에 정의되어 있는 매크로의 일부는 내부(비공개)로 간주되지만 매크로 정의는 그러한 범위는 존재하지 않고, 호출되는 코드와 사용자 템플릿에 모든 매크로가 표시된다. 다음 섹션에서는 템플릿에서 직접 호출할 필요가 있는 매크로에만 초점을 맞추고 있다. 매크로 코드를 직접 표시하는 경우, 파일 `spring.ftl`이라고 하는 `org.springframework.web.reactive.result.view.freemarker` 패키지에 포함되어 있다. 바인딩 지원에 대한 자세한 내용은 Spring MVC의 [간단한 바인딩](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-simple-binding)을 참조해라. ### 폼 매크로(Form Macros) FreeMarker 템플릿에 대한 Spring의 폼 매크로 지원에 대한 자세한 내용은 Spring MVC 문서의 다음 섹션을 참조해라. - [입력 매크로 - Input Macros](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-views-form-macros) - [입력 필드- Input Fields](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-views-form-macros-input) - [선택 필드 - Selection Fields](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-views-form-macros-select) - [HTML 이스케이프 - HTML Escaping](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-views-form-macros-html-escaping) ## 1.9.3. 스크립트보기 [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-script) Spring Framework에는 [JSR-223](https://www.jcp.org/en/jsr/detail?id=223) Java 스크립트 엔진에서 실행할 수 있는 템플릿 라이브러리에 Spring WebFlux을 사용하기 위한 기본 제공 통합이 포함되어 있다. 다음 표는 다양한 스크립트 엔진에서 테스트 템플릿 라이브러리를 보여준다. | 스크립트 라이브러리 | 스크립트 엔진 | |--|--| | [Handlebars](https://handlebarsjs.com) | [Nashorn](https://openjdk.java.net/projects/nashorn/) | | [Mustache](https://mustache.github.io/) | [Nashorn](https://openjdk.java.net/projects/nashorn/) | | [React](https://reactjs.org/) | [Nashorn](https://openjdk.java.net/projects/nashorn/) | | [EJS](https://www.embeddedjs.com/) | [Nashorn](https://openjdk.java.net/projects/nashorn/) | | [ERB](https://www.stuartellis.name/articles/erb/) | [JRuby](https://www.jruby.org/) | | [String templates](https://docs.python.org/2/library/string.html#template-strings) | [Jython](https://www.jython.org/) | | [Kotlin 스크립트 템플릿](https://github.com/sdeleuze/kotlin-script-templating) | [Kotlin](https://kotlinlang.org/) | > 다른 스크립트 엔진을 통합하기 위한 기본적인 규칙은 `ScriptEngine` 및 `Invocable` 인터페이스를 구현할 필요가 있다는 것이다. ### 요구 사항 [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-script-dependencies) 클래스 경로에 스크립트 엔진이 필요한다. 자세한 내용은 스크립트 엔진에 따라 달라진다. - [Nashorn](https://openjdk.java.net/projects/nashorn/) JavaScript 엔진은 Java 8+가 포함되어 있다. 사용 가능한 최신 업데이트 자료를 사용하는 것이 좋다. - [JRuby](https://www.jruby.org/)는 Ruby 지원의 종속성으로 추가해야 한다. - [Jython](https://www.jython.org/)는 Python 지원의 종속성으로 추가해야 한다. - Kotlin 스크립트를 지원하려면 `org.jetbrains.kotlin:kotlin-script-util` 종속성과 `org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory` 행을 포함하는 `META-INF/services/javax.script.ScriptEngineFactory` 파일을 추가해야 한다. 자세한 내용은 [예제](https://github.com/sdeleuze/kotlin-script-templating)을 참조해라. 스크립트 템플릿 라이브러리가 필요한다. Javascript에서 이렇게 하나의 방법은 [WebJars](https://www.webjars.org/)을 사용하는 것이다. ### 스크립트 템플릿(Script Templates) [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-script-integrate) `ScriptTemplateConfigurer` Bean을 선언하고 사용하는 스크립트 엔진을 로드하는 스크립트 파일 템플릿을 렌더링하기 위해 호출하는 함수 등을 지정할 수 있다. 다음 예제에서는 Mustache 템플릿과 Nashorn JavaScript 엔진을 사용하고 있다. Java ``` @Configuration @EnableWebFlux public class WebConfig implements WebFluxConfigurer { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.scriptTemplate(); } @Bean public ScriptTemplateConfigurer configurer() { ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer(); configurer.setEngineName("nashorn"); configurer.setScripts("mustache.js"); configurer.setRenderObject("Mustache"); configurer.setRenderFunction("render"); return configurer; } } ``` Kotlin ``` @Configuration @EnableWebFlux class WebConfig : WebFluxConfigurer { override fun configureViewResolvers(registry: ViewResolverRegistry) { registry.scriptTemplate() } @Bean fun configurer() = ScriptTemplateConfigurer().apply { engineName = "nashorn" setScripts("mustache.js") renderObject = "Mustache" renderFunction = "render" } } ``` `render` 함수는 다음 매개 변수로 호출된다. - `String template`: 템플릿의 내용 - `Map model`: 뷰 모델 - `RenderingContext renderingContext`: 응용 프로그램 컨텍스트 로케일 템플릿 로더, URL에 대한 액세스를 제공하는 [`RenderingContext`](https://docs.spring.io/spring-framework/docs/5.3.5/javadoc-api/org/springframework/web/servlet/view/script/RenderingContext.html)(5.0 이상) `Mustache.render()`은 서명과 기본적으로 호환성이 있기 때문에 직접 호출 할 수 있다. 템플릿 기술로 사용자가 필요한 경우 사용자 정의 렌더링 기능을 구현하는 스크립트를 제공 할 수 있다. 예 : [`Handlerbars`](https://handlebarsjs.com/) (영문) 사용하기 전에 템플릿을 컴파일해야 서버 사이드 스크립트 엔진에서 사용할 수없는 브라우저 기능을 에뮬레이트하기 위해 [`polyfill`](https://en.wikipedia.org/wiki/Polyfill)가 필요한다. 다음 예제에서는 사용자 지정 렌더링 함수를 설정하는 방법을 보여준다. Java ``` @Configuration @EnableWebFlux public class WebConfig implements WebFluxConfigurer { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.scriptTemplate(); } @Bean public ScriptTemplateConfigurer configurer() { ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer(); configurer.setEngineName("nashorn"); configurer.setScripts("polyfill.js", "handlebars.js", "render.js"); configurer.setRenderFunction("render"); configurer.setSharedEngine(false); return configurer; } } ``` Kotlin ``` @Configuration @EnableWebFlux class WebConfig : WebFluxConfigurer { override fun configureViewResolvers(registry: ViewResolverRegistry) { registry.scriptTemplate() } @Bean fun configurer() = ScriptTemplateConfigurer().apply { engineName = "nashorn" setScripts("polyfill.js", "handlebars.js", "render.js") renderFunction = "render" isSharedEngine = false } } ``` > Nashorn에서 실행되는 Handlebars과 React 등 동시 실행을 위해 설계되지 않은 템플릿 라이브러리에서 비 스레드 안전 스크립트 엔진을 사용하는 경우는 `sharedEngine` 속성을 ` false` 설정해야 한다. 이 경우 [이 버그](https://bugs.openjdk.java.net/browse/JDK-8076099) 때문에 Java SE 8 update 60이 필요하지만, 일반적으로 최신의 Java SE 패치 릴리스를 사용하는 것이 좋습니다. `polyfill.js` 다음 조각이 같이 Handlebars가 제대로 실행하는데 필요한 `window` 개체만 정의한다. ``` var window = {}; ``` 이 기본 `render.js` 구현은 템플릿을 사용하기 전에 컴파일한다. 또한 실전 대응의 구현에서는 캐시 된 템플릿 또는 미리 컴파일 된 템플릿을 저장하고 재사용해야한다. 이것은 필요한 사용자 (예를 들어, 템플릿 엔진의 구성 관리)뿐만 아니라 스크립트 측에서도 실행할 수 있다. 다음 예제는 템플릿의 컴파일 방법을 보여준다. ``` function render(template, model) { var compiledTemplate = Handlebars.compile(template); return compiledTemplate(model); } ``` 다른 구성 예는 Spring Framework 단위 테스트, [Java](https://github.com/spring-projects/spring-framework/tree/master/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script), [resources](https://github.com/spring-projects/spring-framework/tree/master/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script)을 참조해라. ## 1.9.4. JSON과 XML [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-view-jackson) [내용 협상(Content Negotiation )](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-multiple-representations)의 목적은 클라이언트에서 요청된 콘텐츠 형식에 따라 HTML 템플리트를 사용하여 모델의 렌더링과 다른 형식 (JSON 또는 XML 등)로 렌더링을 전환 할 수 있는 편리한다. 이렇게 하는 것을 지원하기 위해 Spring WebFlux은 `HttpMessageWriterView`을 제공한다. 이것을 사용하여 `Jackson2JsonEncoder`, `Jackson2SmileEncoder`, `Jaxb2XmlEncoder` 등을 `spring-web`에서 사용 가능한 [코덱](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-codecs) 중 하나를 플러그인 할 수 있다. 다른 뷰 기술과 달리 `HttpMessageWriterView`와 `ViewResolver`를 필요로 하지 않고, 대신 기본 뷰로 [설정](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-config-view-resolvers) 된다. 다른 `HttpMessageWriter` 인스턴스 또는 `Encoder` 인스턴스를 감싸고 이러한 기본 뷰를 하나 이상 구성 할 수 있다. 요청된 콘텐츠 형식에 일치하는 항목이 실행될 때 사용된다. 대부분의 경우 모델에 여러 속성이 포함된다. 어느 것을 직렬화하는 방법을 결정하기 위해 렌더링에 사용하는 모델 속성의 이름으로 `HttpMessageWriterView`을 구성 할 수 있다. 모델에 포함된 속성이 하나의 경우 그 특성이 사용된다.

이전 글 : 1.8. Web 보안
다음 글 : 1.10. HTTP 캐싱