Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#512: Add beans access for reactive app #513

Merged
merged 2 commits into from
May 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/src/orchid/resources/changelog/v3_1_4.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ version: '3.1.4'
- Slice filter: Use collection size when toIndex is greater than collection size (#504)
- Adjust spring boot doc (#509)
- Build with jdk14 (#508)
- Set proxyBeanMethods to false (#507)
- Set proxyBeanMethods to false (#507)
- Add access to Spring Beans/request/session and response when using Pebble with WebFlux (#512)
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ class PebbleServletWebConfiguration extends AbstractPebbleConfiguration {
@ConditionalOnMissingBean(name = "pebbleViewResolver")
PebbleViewResolver pebbleViewResolver(PebbleProperties properties,
PebbleEngine pebbleEngine) {
PebbleViewResolver pvr = new PebbleViewResolver();
PebbleViewResolver pvr = new PebbleViewResolver(pebbleEngine);
properties.applyToMvcViewResolver(pvr);

pvr.setPebbleEngine(pebbleEngine);
if (pebbleEngine.getLoader() instanceof ClasspathLoader) {
// classpathloader doesn't like leading slashes in paths
pvr.setPrefix(this.stripLeadingSlash(properties.getPrefix()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ public String extensions() {
return "extensions";
}

@RequestMapping("/beans.action")
public String beans() {
return "beans";
}

@RequestMapping("/response.action")
public String response() {
return "responseObject";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.mitchellbosecke.pebble.boot;

import org.springframework.stereotype.Component;

@Component
public class Foo {

public String value = "bar";
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void testRequestAccess() throws Exception {
.expectBody(String.class)
.returnResult().getResponseBody();

assertThat(result).isEqualTo("ctx path:");
assertThat(result).isEqualTo("ctx path:/contextPath.action");
}

@Test
Expand Down Expand Up @@ -74,5 +74,27 @@ void testAdditionalExtensions() throws Exception {

assertThat(result).isEqualTo("Hola Boot! Tested!");
}

@Test
void testBeansAccess() throws Exception {
String result = this.client.get().uri("/beans.action").exchange()
.expectStatus().isOk()
.expectHeader().contentTypeCompatibleWith(MediaType.TEXT_HTML)
.expectBody(String.class)
.returnResult().getResponseBody();

assertThat(result).isEqualTo("beans:bar");
}

@Test
void testResponseAccess() throws Exception {
String result = this.client.get().uri("/response.action").exchange()
.expectStatus().isOk()
.expectHeader().contentTypeCompatibleWith(MediaType.TEXT_HTML)
.expectBody(String.class)
.returnResult().getResponseBody();

assertThat(result).isEqualTo("response:200 OK");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,19 @@ void testAdditionalExtensions() throws Exception {
.andExpect(content().string("Hola Boot! Tested!"));
}

@Test
void testBeansAccess() throws Exception {
this.mockMvc.perform(get("/beans.action"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_HTML))
.andExpect(content().string("beans:bar"));
}

@Test
void testResponseAccess() throws Exception {
this.mockMvc.perform(get("/response.action"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_HTML))
.andExpect(content().string("response:200"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
beans:{{beans.foo.value}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ctx path:{{request.contextPath}}
ctx path:{{request.contextPath}}{{request.path}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
response:{{response.status}}{{response.statusCode}}
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package com.mitchellbosecke.pebble.spring.reactive;

import static java.util.Optional.ofNullable;

import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.error.PebbleException;
import com.mitchellbosecke.pebble.spring.context.Beans;
import com.mitchellbosecke.pebble.template.PebbleTemplate;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.Map;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
Expand All @@ -12,20 +20,16 @@
import org.springframework.util.MimeType;
import org.springframework.web.reactive.result.view.AbstractUrlBasedView;
import org.springframework.web.server.ServerWebExchange;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.Map;

import static java.util.Optional.ofNullable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class PebbleReactiveView extends AbstractUrlBasedView {

private static final String BEANS_VARIABLE_NAME = "beans";
private static final String REQUEST_VARIABLE_NAME = "request";
private static final String RESPONSE_VARIABLE_NAME = "response";
private static final String SESSION_VARIABLE_NAME = "session";

private PebbleEngine pebbleEngine;
private String templateName;

Expand All @@ -47,6 +51,7 @@ protected Mono<Void> renderInternal(Map<String, Object> renderAttributes,
try {
Charset charset = this.getCharset(contentType);
Writer writer = new OutputStreamWriter(dataBuffer.asOutputStream(), charset);
this.addVariablesToModel(renderAttributes, exchange);
this.evaluateTemplate(renderAttributes, locale, writer);
} catch (Exception ex) {
DataBufferUtils.release(dataBuffer);
Expand All @@ -55,6 +60,13 @@ protected Mono<Void> renderInternal(Map<String, Object> renderAttributes,
return exchange.getResponse().writeWith(Flux.just(dataBuffer));
}

private void addVariablesToModel(Map<String, Object> model, ServerWebExchange exchange) {
model.put(BEANS_VARIABLE_NAME, new Beans(this.getApplicationContext()));
model.put(REQUEST_VARIABLE_NAME, exchange.getRequest());
model.put(RESPONSE_VARIABLE_NAME, exchange.getResponse());
model.put(SESSION_VARIABLE_NAME, exchange.getSession());
}

private Charset getCharset(@Nullable MediaType mediaType) {
return ofNullable(mediaType)
.map(MimeType::getCharset)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.mitchellbosecke.pebble.spring.reactive;

import com.mitchellbosecke.pebble.PebbleEngine;

import org.springframework.web.reactive.result.view.AbstractUrlBasedView;
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;

Expand All @@ -27,8 +26,4 @@ protected AbstractUrlBasedView createView(String viewName) {
protected Class<?> requiredViewClass() {
return PebbleReactiveView.class;
}

public PebbleEngine getPebbleEngine() {
return this.pebbleEngine;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@

import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.loader.Loader;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
import org.springframework.web.servlet.view.AbstractUrlBasedView;

public class PebbleViewResolver extends AbstractTemplateViewResolver implements InitializingBean {

private String characterEncoding = "UTF-8";
private PebbleEngine pebbleEngine;
private final PebbleEngine pebbleEngine;

public PebbleViewResolver() {
public PebbleViewResolver(PebbleEngine pebbleEngine) {
this.pebbleEngine = pebbleEngine;
this.setViewClass(this.requiredViewClass());
}

Expand All @@ -34,11 +33,6 @@ public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
}

@Required
public void setPebbleEngine(PebbleEngine pebbleEngine) {
this.pebbleEngine = pebbleEngine;
}

@Override
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
PebbleView view = (PebbleView) super.buildView(viewName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,9 @@ public Loader<?> templateLoader() {

@Bean
public ViewResolver viewResolver(PebbleEngine pebbleEngine) {
PebbleViewResolver viewResolver = new PebbleViewResolver();
PebbleViewResolver viewResolver = new PebbleViewResolver(pebbleEngine);
viewResolver.setPrefix("com/mitchellbosecke/pebble/spring/template/");
viewResolver.setSuffix(".html");
viewResolver.setPebbleEngine(pebbleEngine);
viewResolver.setContentType("text/html");
return viewResolver;
}
Expand Down