1616
1717package org .springframework .boot .autoconfigure .freemarker ;
1818
19+ import java .nio .charset .Charset ;
20+ import java .nio .charset .StandardCharsets ;
1921import java .util .HashMap ;
22+ import java .util .LinkedHashMap ;
2023import java .util .Map ;
2124
22- import org .springframework .boot .autoconfigure .template .AbstractTemplateViewResolverProperties ;
2325import org .springframework .boot .context .properties .ConfigurationProperties ;
26+ import org .springframework .core .Ordered ;
27+ import org .springframework .util .Assert ;
28+ import org .springframework .util .MimeType ;
29+ import org .springframework .web .servlet .view .AbstractTemplateViewResolver ;
2430
2531/**
2632 * {@link ConfigurationProperties @ConfigurationProperties} for configuring FreeMarker.
3036 * @since 1.1.0
3137 */
3238@ ConfigurationProperties ("spring.freemarker" )
33- public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties {
39+ public class FreeMarkerProperties {
3440
3541 public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/" ;
3642
3743 public static final String DEFAULT_PREFIX = "" ;
3844
3945 public static final String DEFAULT_SUFFIX = ".ftlh" ;
4046
47+ private static final MimeType DEFAULT_CONTENT_TYPE = MimeType .valueOf ("text/html" );
48+
49+ private static final Charset DEFAULT_CHARSET = StandardCharsets .UTF_8 ;
50+
51+ /**
52+ * Whether to enable MVC view resolution for this technology.
53+ */
54+ private boolean enabled = true ;
55+
56+ /**
57+ * Whether to enable template caching.
58+ */
59+ private boolean cache ;
60+
61+ /**
62+ * Content-Type value.
63+ */
64+ private MimeType contentType = DEFAULT_CONTENT_TYPE ;
65+
66+ /**
67+ * Template encoding.
68+ */
69+ private Charset charset = DEFAULT_CHARSET ;
70+
71+ /**
72+ * View names that can be resolved.
73+ */
74+ private String [] viewNames ;
75+
76+ /**
77+ * Whether to check that the templates location exists.
78+ */
79+ private boolean checkTemplateLocation = true ;
80+
81+ /**
82+ * Prefix that gets prepended to view names when building a URL.
83+ */
84+ private String prefix = DEFAULT_PREFIX ;
85+
86+ /**
87+ * Suffix that gets appended to view names when building a URL.
88+ */
89+ private String suffix = DEFAULT_SUFFIX ;
90+
91+ /**
92+ * Name of the RequestContext attribute for all views.
93+ */
94+ private String requestContextAttribute ;
95+
96+ /**
97+ * Whether all request attributes should be added to the model prior to merging with
98+ * the template.
99+ */
100+ private boolean exposeRequestAttributes = false ;
101+
102+ /**
103+ * Whether all HttpSession attributes should be added to the model prior to merging
104+ * with the template.
105+ */
106+ private boolean exposeSessionAttributes = false ;
107+
108+ /**
109+ * Whether HttpServletRequest attributes are allowed to override (hide) controller
110+ * generated model attributes of the same name.
111+ */
112+ private boolean allowRequestOverride = false ;
113+
114+ /**
115+ * Whether to expose a RequestContext for use by Spring's macro library, under the
116+ * name "springMacroRequestContext".
117+ */
118+ private boolean exposeSpringMacroHelpers = true ;
119+
120+ /**
121+ * Whether HttpSession attributes are allowed to override (hide) controller generated
122+ * model attributes of the same name.
123+ */
124+ private boolean allowSessionOverride = false ;
125+
41126 /**
42127 * Well-known FreeMarker keys which are passed to FreeMarker's Configuration.
43128 */
@@ -56,8 +141,62 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties
56141 */
57142 private boolean preferFileSystemAccess ;
58143
59- public FreeMarkerProperties () {
60- super (DEFAULT_PREFIX , DEFAULT_SUFFIX );
144+ public void setEnabled (boolean enabled ) {
145+ this .enabled = enabled ;
146+ }
147+
148+ public boolean isEnabled () {
149+ return this .enabled ;
150+ }
151+
152+ public void setCheckTemplateLocation (boolean checkTemplateLocation ) {
153+ this .checkTemplateLocation = checkTemplateLocation ;
154+ }
155+
156+ public boolean isCheckTemplateLocation () {
157+ return this .checkTemplateLocation ;
158+ }
159+
160+ public String [] getViewNames () {
161+ return this .viewNames ;
162+ }
163+
164+ public void setViewNames (String [] viewNames ) {
165+ this .viewNames = viewNames ;
166+ }
167+
168+ public boolean isCache () {
169+ return this .cache ;
170+ }
171+
172+ public void setCache (boolean cache ) {
173+ this .cache = cache ;
174+ }
175+
176+ public MimeType getContentType () {
177+ if (this .contentType .getCharset () == null ) {
178+ Map <String , String > parameters = new LinkedHashMap <>();
179+ parameters .put ("charset" , this .charset .name ());
180+ parameters .putAll (this .contentType .getParameters ());
181+ return new MimeType (this .contentType , parameters );
182+ }
183+ return this .contentType ;
184+ }
185+
186+ public void setContentType (MimeType contentType ) {
187+ this .contentType = contentType ;
188+ }
189+
190+ public Charset getCharset () {
191+ return this .charset ;
192+ }
193+
194+ public String getCharsetName () {
195+ return (this .charset != null ) ? this .charset .name () : null ;
196+ }
197+
198+ public void setCharset (Charset charset ) {
199+ this .charset = charset ;
61200 }
62201
63202 public Map <String , String > getSettings () {
@@ -84,4 +223,96 @@ public void setPreferFileSystemAccess(boolean preferFileSystemAccess) {
84223 this .preferFileSystemAccess = preferFileSystemAccess ;
85224 }
86225
226+ public String getPrefix () {
227+ return this .prefix ;
228+ }
229+
230+ public void setPrefix (String prefix ) {
231+ this .prefix = prefix ;
232+ }
233+
234+ public String getSuffix () {
235+ return this .suffix ;
236+ }
237+
238+ public void setSuffix (String suffix ) {
239+ this .suffix = suffix ;
240+ }
241+
242+ public String getRequestContextAttribute () {
243+ return this .requestContextAttribute ;
244+ }
245+
246+ public void setRequestContextAttribute (String requestContextAttribute ) {
247+ this .requestContextAttribute = requestContextAttribute ;
248+ }
249+
250+ public boolean isExposeRequestAttributes () {
251+ return this .exposeRequestAttributes ;
252+ }
253+
254+ public void setExposeRequestAttributes (boolean exposeRequestAttributes ) {
255+ this .exposeRequestAttributes = exposeRequestAttributes ;
256+ }
257+
258+ public boolean isExposeSessionAttributes () {
259+ return this .exposeSessionAttributes ;
260+ }
261+
262+ public void setExposeSessionAttributes (boolean exposeSessionAttributes ) {
263+ this .exposeSessionAttributes = exposeSessionAttributes ;
264+ }
265+
266+ public boolean isAllowRequestOverride () {
267+ return this .allowRequestOverride ;
268+ }
269+
270+ public void setAllowRequestOverride (boolean allowRequestOverride ) {
271+ this .allowRequestOverride = allowRequestOverride ;
272+ }
273+
274+ public boolean isAllowSessionOverride () {
275+ return this .allowSessionOverride ;
276+ }
277+
278+ public void setAllowSessionOverride (boolean allowSessionOverride ) {
279+ this .allowSessionOverride = allowSessionOverride ;
280+ }
281+
282+ public boolean isExposeSpringMacroHelpers () {
283+ return this .exposeSpringMacroHelpers ;
284+ }
285+
286+ public void setExposeSpringMacroHelpers (boolean exposeSpringMacroHelpers ) {
287+ this .exposeSpringMacroHelpers = exposeSpringMacroHelpers ;
288+ }
289+
290+ /**
291+ * Apply the given properties to a {@link AbstractTemplateViewResolver}. Use Object in
292+ * signature to avoid runtime dependency on MVC, which means that the template engine
293+ * can be used in a non-web application.
294+ * @param viewResolver the resolver to apply the properties to.
295+ */
296+ public void applyToMvcViewResolver (Object viewResolver ) {
297+ Assert .isInstanceOf (AbstractTemplateViewResolver .class , viewResolver ,
298+ () -> "ViewResolver is not an instance of AbstractTemplateViewResolver :" + viewResolver );
299+ AbstractTemplateViewResolver resolver = (AbstractTemplateViewResolver ) viewResolver ;
300+ resolver .setPrefix (getPrefix ());
301+ resolver .setSuffix (getSuffix ());
302+ resolver .setCache (isCache ());
303+ if (getContentType () != null ) {
304+ resolver .setContentType (getContentType ().toString ());
305+ }
306+ resolver .setViewNames (getViewNames ());
307+ resolver .setExposeRequestAttributes (isExposeRequestAttributes ());
308+ resolver .setAllowRequestOverride (isAllowRequestOverride ());
309+ resolver .setAllowSessionOverride (isAllowSessionOverride ());
310+ resolver .setExposeSessionAttributes (isExposeSessionAttributes ());
311+ resolver .setExposeSpringMacroHelpers (isExposeSpringMacroHelpers ());
312+ resolver .setRequestContextAttribute (getRequestContextAttribute ());
313+ // The resolver usually acts as a fallback resolver (e.g. like a
314+ // InternalResourceViewResolver) so it needs to have low precedence
315+ resolver .setOrder (Ordered .LOWEST_PRECEDENCE - 5 );
316+ }
317+
87318}
0 commit comments