Consistent ScriptTemplateView locale resolution via request
Issue: SPR-15064
This commit is contained in:
parent
41eaf03bc8
commit
98642c7e29
|
|
@ -40,6 +40,7 @@ public class RenderingContext {
|
||||||
|
|
||||||
public RenderingContext(ApplicationContext applicationContext, Locale locale,
|
public RenderingContext(ApplicationContext applicationContext, Locale locale,
|
||||||
Function<String, String> templateLoader, String url) {
|
Function<String, String> templateLoader, String url) {
|
||||||
|
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.templateLoader = templateLoader;
|
this.templateLoader = templateLoader;
|
||||||
|
|
@ -48,19 +49,19 @@ public class RenderingContext {
|
||||||
|
|
||||||
|
|
||||||
public ApplicationContext getApplicationContext() {
|
public ApplicationContext getApplicationContext() {
|
||||||
return applicationContext;
|
return this.applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Locale getLocale() {
|
public Locale getLocale() {
|
||||||
return locale;
|
return this.locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Function<String, String> getTemplateLoader() {
|
public Function<String, String> getTemplateLoader() {
|
||||||
return templateLoader;
|
return this.templateLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return this.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextException;
|
import org.springframework.context.ApplicationContextException;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.core.io.buffer.DataBuffer;
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
|
|
@ -58,7 +59,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||||
* {@link ScriptTemplateConfig} bean in the web application context and using
|
* {@link ScriptTemplateConfig} bean in the web application context and using
|
||||||
* it to obtain the configured properties.
|
* it to obtain the configured properties.
|
||||||
*
|
*
|
||||||
* <p>Nashorn Javascript engine requires Java 8+, and may require setting the
|
* <p>The Nashorn JavaScript engine requires Java 8+ and may require setting the
|
||||||
* {@code sharedEngine} property to {@code false} in order to run properly. See
|
* {@code sharedEngine} property to {@code false} in order to run properly. See
|
||||||
* {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} for more details.
|
* {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} for more details.
|
||||||
*
|
*
|
||||||
|
|
@ -77,8 +78,6 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
|
||||||
|
|
||||||
private String engineName;
|
private String engineName;
|
||||||
|
|
||||||
private Locale locale;
|
|
||||||
|
|
||||||
private Boolean sharedEngine;
|
private Boolean sharedEngine;
|
||||||
|
|
||||||
private String[] scripts;
|
private String[] scripts;
|
||||||
|
|
@ -123,13 +122,6 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
|
||||||
this.engineName = engineName;
|
this.engineName = engineName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the {@link Locale} to pass to the render function.
|
|
||||||
*/
|
|
||||||
public void setLocale(Locale locale) {
|
|
||||||
this.locale = locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} documentation.
|
* See {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} documentation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -312,8 +304,9 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Locale locale = LocaleContextHolder.getLocale(exchange.getLocaleContext());
|
||||||
RenderingContext context = new RenderingContext(
|
RenderingContext context = new RenderingContext(
|
||||||
obtainApplicationContext(), this.locale, templateLoader, url);
|
obtainApplicationContext(), locale, templateLoader, url);
|
||||||
|
|
||||||
Object html;
|
Object html;
|
||||||
if (this.renderFunction == null) {
|
if (this.renderFunction == null) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,12 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.web.reactive.result.view.script;
|
package org.springframework.web.reactive.result.view.script;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
|
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
|
||||||
import org.springframework.web.reactive.result.view.View;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience subclass of {@link UrlBasedViewResolver} that supports
|
* Convenience subclass of {@link UrlBasedViewResolver} that supports
|
||||||
|
|
@ -60,13 +55,6 @@ public class ScriptTemplateViewResolver extends UrlBasedViewResolver {
|
||||||
setSuffix(suffix);
|
setSuffix(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<View> resolveViewName(String viewName, Locale locale) {
|
|
||||||
return super.resolveViewName(viewName, locale).map(view -> {
|
|
||||||
((ScriptTemplateView)view).setLocale(locale);
|
|
||||||
return view;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> requiredViewClass() {
|
protected Class<?> requiredViewClass() {
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,7 @@ public class KotlinScriptTemplateTests {
|
||||||
|
|
||||||
private MockServerHttpResponse renderViewWithModel(String viewUrl, Map<String, Object> model, Locale locale, Class<?> configuration) throws Exception {
|
private MockServerHttpResponse renderViewWithModel(String viewUrl, Map<String, Object> model, Locale locale, Class<?> configuration) throws Exception {
|
||||||
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);
|
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);
|
||||||
view.setLocale(locale);
|
MockServerWebExchange exchange = MockServerHttpRequest.get("/").acceptLanguageAsLocales(locale).toExchange();
|
||||||
MockServerWebExchange exchange = MockServerHttpRequest.get("/").toExchange();
|
|
||||||
view.renderInternal(model, MediaType.TEXT_HTML, exchange).block();
|
view.renderInternal(model, MediaType.TEXT_HTML, exchange).block();
|
||||||
return exchange.getResponse();
|
return exchange.getResponse();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ public class RenderingContext {
|
||||||
|
|
||||||
public RenderingContext(ApplicationContext applicationContext, Locale locale,
|
public RenderingContext(ApplicationContext applicationContext, Locale locale,
|
||||||
Function<String, String> templateLoader, String url) {
|
Function<String, String> templateLoader, String url) {
|
||||||
|
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.templateLoader = templateLoader;
|
this.templateLoader = templateLoader;
|
||||||
|
|
@ -48,19 +49,19 @@ public class RenderingContext {
|
||||||
|
|
||||||
|
|
||||||
public ApplicationContext getApplicationContext() {
|
public ApplicationContext getApplicationContext() {
|
||||||
return applicationContext;
|
return this.applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Locale getLocale() {
|
public Locale getLocale() {
|
||||||
return locale;
|
return this.locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Function<String, String> getTemplateLoader() {
|
public Function<String, String> getTemplateLoader() {
|
||||||
return templateLoader;
|
return this.templateLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return this.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ import org.springframework.util.Assert;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||||
import org.springframework.web.servlet.view.AbstractUrlBasedView;
|
import org.springframework.web.servlet.view.AbstractUrlBasedView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,7 +60,7 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView;
|
||||||
* {@link ScriptTemplateConfig} bean in the web application context and using
|
* {@link ScriptTemplateConfig} bean in the web application context and using
|
||||||
* it to obtain the configured properties.
|
* it to obtain the configured properties.
|
||||||
*
|
*
|
||||||
* <p>Nashorn Javascript engine requires Java 8+, and may require setting the
|
* <p>The Nashorn JavaScript engine requires Java 8+ and may require setting the
|
||||||
* {@code sharedEngine} property to {@code false} in order to run properly. See
|
* {@code sharedEngine} property to {@code false} in order to run properly. See
|
||||||
* {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} for more details.
|
* {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} for more details.
|
||||||
*
|
*
|
||||||
|
|
@ -86,8 +87,6 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
|
||||||
|
|
||||||
private String engineName;
|
private String engineName;
|
||||||
|
|
||||||
private Locale locale;
|
|
||||||
|
|
||||||
private Boolean sharedEngine;
|
private Boolean sharedEngine;
|
||||||
|
|
||||||
private String[] scripts;
|
private String[] scripts;
|
||||||
|
|
@ -130,14 +129,6 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the {@link Locale} to pass to the render function.
|
|
||||||
* @since 5.0
|
|
||||||
*/
|
|
||||||
public void setLocale(Locale locale) {
|
|
||||||
this.locale = locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link ScriptTemplateConfigurer#setEngineName(String)} documentation.
|
* See {@link ScriptTemplateConfigurer#setEngineName(String)} documentation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -362,6 +353,7 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
|
||||||
String url = getUrl();
|
String url = getUrl();
|
||||||
Assert.state(url != null, "'url' not set");
|
Assert.state(url != null, "'url' not set");
|
||||||
String template = getTemplate(url);
|
String template = getTemplate(url);
|
||||||
|
|
||||||
Function<String, String> templateLoader = path -> {
|
Function<String, String> templateLoader = path -> {
|
||||||
try {
|
try {
|
||||||
return getTemplate(path);
|
return getTemplate(path);
|
||||||
|
|
@ -370,7 +362,9 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
RenderingContext context = new RenderingContext(obtainApplicationContext(), this.locale, templateLoader, url);
|
|
||||||
|
Locale locale = RequestContextUtils.getLocale(request);
|
||||||
|
RenderingContext context = new RenderingContext(obtainApplicationContext(), locale, templateLoader, url);
|
||||||
|
|
||||||
Object html;
|
Object html;
|
||||||
if (this.renderFunction == null) {
|
if (this.renderFunction == null) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,9 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.view.script;
|
package org.springframework.web.servlet.view.script;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.springframework.web.servlet.View;
|
|
||||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,14 +56,6 @@ public class ScriptTemplateViewResolver extends UrlBasedViewResolver {
|
||||||
setSuffix(suffix);
|
setSuffix(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public View resolveViewName(String viewName, Locale locale) throws Exception {
|
|
||||||
ScriptTemplateView view = (ScriptTemplateView)super.resolveViewName(viewName, locale);
|
|
||||||
if (view != null) {
|
|
||||||
view.setLocale(locale);
|
|
||||||
}
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> requiredViewClass() {
|
protected Class<?> requiredViewClass() {
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,9 @@ public class KotlinScriptTemplateTests {
|
||||||
|
|
||||||
private MockHttpServletResponse renderViewWithModel(String viewUrl, Map<String, Object> model, Locale locale, Class<?> configuration) throws Exception {
|
private MockHttpServletResponse renderViewWithModel(String viewUrl, Map<String, Object> model, Locale locale, Class<?> configuration) throws Exception {
|
||||||
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);
|
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);
|
||||||
view.setLocale(locale);
|
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addPreferredLocale(locale);
|
||||||
view.renderMergedOutputModel(model, request, response);
|
view.renderMergedOutputModel(model, request, response);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue