1
1
/*
2
- * Copyright 2002-2021 the original author or authors.
2
+ * Copyright 2002-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
28
28
import freemarker .template .SimpleHash ;
29
29
import freemarker .template .Template ;
30
30
import freemarker .template .TemplateException ;
31
+ import freemarker .template .TemplateModel ;
32
+ import freemarker .template .TemplateModelException ;
31
33
import jakarta .servlet .ServletContext ;
32
34
import jakarta .servlet .http .HttpServletRequest ;
33
35
import jakarta .servlet .http .HttpServletResponse ;
59
61
* of this approach.
60
62
*
61
63
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3 or higher.
64
+ * As of Spring Framework 6.0, FreeMarker templates are rendered in a minimal
65
+ * fashion without JSP support, just exposing request attributes in addition
66
+ * to the MVC-provided model map for alignment with common Servlet resources.
62
67
*
63
68
* @author Darren Davison
64
69
* @author Juergen Hoeller
@@ -235,9 +240,6 @@ protected void exposeHelpers(Map<String, Object> model, HttpServletRequest reque
235
240
* bean property, retrieved via {@code getTemplate}. It delegates to the
236
241
* {@code processTemplate} method to merge the template instance with
237
242
* the given template model.
238
- * <p>Adds the standard Freemarker hash models to the model: request parameters,
239
- * request, session and application (ServletContext), as well as the JSP tag
240
- * library hash model.
241
243
* <p>Can be overridden to customize the behavior, for example to render
242
244
* multiple templates into a single view.
243
245
* @param model the model to use for rendering
@@ -256,7 +258,7 @@ protected void doRender(Map<String, Object> model, HttpServletRequest request,
256
258
257
259
// Expose model to JSP tags (as request attributes).
258
260
exposeModelAsRequestAttributes (model , request );
259
- // Expose all standard FreeMarker hash models .
261
+ // Expose FreeMarker hash model .
260
262
SimpleHash fmModel = buildTemplateModel (model , request , response );
261
263
262
264
// Grab the locale-specific version of the template.
@@ -266,7 +268,8 @@ protected void doRender(Map<String, Object> model, HttpServletRequest request,
266
268
267
269
/**
268
270
* Build a FreeMarker template model for the given model Map.
269
- * <p>The default implementation builds a {@link SimpleHash}.
271
+ * <p>The default implementation builds a {@link SimpleHash} for the
272
+ * given MVC model with an additional fallback to request attributes.
270
273
* @param model the model to use for rendering
271
274
* @param request current HTTP request
272
275
* @param response current servlet response
@@ -275,7 +278,7 @@ protected void doRender(Map<String, Object> model, HttpServletRequest request,
275
278
protected SimpleHash buildTemplateModel (Map <String , Object > model , HttpServletRequest request ,
276
279
HttpServletResponse response ) {
277
280
278
- SimpleHash fmModel = new SimpleHash (getObjectWrapper ());
281
+ SimpleHash fmModel = new RequestHashModel (getObjectWrapper (), request );
279
282
fmModel .putAll (model );
280
283
return fmModel ;
281
284
}
@@ -329,4 +332,34 @@ protected void processTemplate(Template template, SimpleHash model, HttpServletR
329
332
template .process (model , response .getWriter ());
330
333
}
331
334
335
+
336
+ /**
337
+ * Extension of FreeMarker {@link SimpleHash}, adding a fallback to request attributes.
338
+ * Similar to the formerly used {@link freemarker.ext.servlet.AllHttpScopesHashModel},
339
+ * just limited to common request attribute exposure.
340
+ */
341
+ @ SuppressWarnings ("serial" )
342
+ private static class RequestHashModel extends SimpleHash {
343
+
344
+ private final HttpServletRequest request ;
345
+
346
+ public RequestHashModel (ObjectWrapper wrapper , HttpServletRequest request ) {
347
+ super (wrapper );
348
+ this .request = request ;
349
+ }
350
+
351
+ @ Override
352
+ public TemplateModel get (String key ) throws TemplateModelException {
353
+ TemplateModel model = super .get (key );
354
+ if (model != null ) {
355
+ return model ;
356
+ }
357
+ Object obj = this .request .getAttribute (key );
358
+ if (obj != null ) {
359
+ return wrap (obj );
360
+ }
361
+ return wrap (null );
362
+ }
363
+ }
364
+
332
365
}
0 commit comments