0
# View Resolution & Templating
1
2
Spring MVC's view resolution system provides flexible rendering of responses using various template engines and view technologies. It supports JSP, Thymeleaf, FreeMarker, and custom view implementations with content negotiation capabilities.
3
4
## Capabilities
5
6
### Core View Classes
7
8
#### AbstractView
9
10
Base class for View implementations providing common functionality for view rendering.
11
12
```java { .api }
13
/**
14
* Abstract base class for View implementations.
15
*/
16
public abstract class AbstractView implements View, BeanNameAware, ApplicationContextAware {
17
18
/** Set the content type for this view */
19
public void setContentType(String contentType);
20
21
/** Get the content type */
22
public String getContentType();
23
24
/** Set the name of the RequestContext attribute */
25
public void setRequestContextAttribute(String requestContextAttribute);
26
27
/** Set static attributes for this view */
28
public void setAttributesMap(Map<String, ?> attributes);
29
30
/** Add a single static attribute */
31
public void addStaticAttribute(String name, Object value);
32
33
/** Set whether to expose path variables to the model */
34
public void setExposePathVariables(boolean exposePathVariables);
35
36
/** Set whether to expose request attributes */
37
public void setExposeRequestAttributes(boolean exposeRequestAttributes);
38
39
/** Set allowed request attributes by name pattern */
40
public void setAllowedRequestAttributes(String... allowedRequestAttributes);
41
42
/** Set whether to expose session attributes */
43
public void setExposeSessionAttributes(boolean exposeSessionAttributes);
44
45
/** Set whether to expose Spring macros for JSP/Velocity */
46
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers);
47
48
/** Template method for rendering the view */
49
protected abstract void renderMergedOutputModel(
50
Map<String, Object> model,
51
HttpServletRequest request,
52
HttpServletResponse response
53
) throws Exception;
54
}
55
```
56
57
#### AbstractUrlBasedView
58
59
Base class for URL-based views that require a URL for rendering.
60
61
```java { .api }
62
/**
63
* Abstract base class for URL-based views.
64
*/
65
public abstract class AbstractUrlBasedView extends AbstractView {
66
67
/** Set the URL for this view */
68
public void setUrl(String url);
69
70
/** Get the URL for this view */
71
public String getUrl();
72
}
73
```
74
75
### ViewResolver Implementations
76
77
#### InternalResourceViewResolver
78
79
ViewResolver for JSP pages and other internal resources.
80
81
```java { .api }
82
/**
83
* Convenient subclass of UrlBasedViewResolver that supports InternalResourceView and subclasses such as JstlView.
84
*/
85
public class InternalResourceViewResolver extends UrlBasedViewResolver {
86
87
/** Set prefix for view names */
88
public void setPrefix(String prefix);
89
90
/** Set suffix for view names */
91
public void setSuffix(String suffix);
92
93
/** Set the view class to use */
94
public void setViewClass(Class<?> viewClass);
95
96
/** Set whether to always include (vs forward) */
97
public void setAlwaysInclude(boolean alwaysInclude);
98
99
/** Set whether to expose context beans as attributes */
100
public void setExposeContextBeansAsAttributes(boolean exposeContextBeansAsAttributes);
101
102
/** Set the names of beans to expose as attributes */
103
public void setExposedContextBeanNames(String... exposedContextBeanNames);
104
}
105
```
106
107
**Usage Example:**
108
109
```java
110
@Configuration
111
public class ViewConfig {
112
113
@Bean
114
public InternalResourceViewResolver jspViewResolver() {
115
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
116
resolver.setPrefix("/WEB-INF/views/");
117
resolver.setSuffix(".jsp");
118
resolver.setViewClass(JstlView.class);
119
resolver.setOrder(2);
120
return resolver;
121
}
122
}
123
```
124
125
#### BeanNameViewResolver
126
127
ViewResolver that interprets view names as Spring bean names.
128
129
```java { .api }
130
/**
131
* Simple implementation of ViewResolver that interprets a view name as a bean name in the current application context.
132
*/
133
public class BeanNameViewResolver implements ViewResolver, Ordered, ApplicationContextAware {
134
135
/** Set the order for this resolver */
136
public void setOrder(int order);
137
138
/** Get the order */
139
public int getOrder();
140
}
141
```
142
143
#### ContentNegotiatingViewResolver
144
145
ViewResolver that resolves views based on content negotiation.
146
147
```java { .api }
148
/**
149
* Implementation that resolves a view based on the request file name or Accept header.
150
*/
151
public class ContentNegotiatingViewResolver implements ViewResolver, Ordered, InitializingBean {
152
153
/** Set content negotiation manager */
154
public void setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager);
155
156
/** Set the list of view resolvers to delegate to */
157
public void setViewResolvers(List<ViewResolver> viewResolvers);
158
159
/** Set default views to consider */
160
public void setDefaultViews(List<View> defaultViews);
161
162
/** Set order for this resolver */
163
public void setOrder(int order);
164
165
/** Set whether to use the Accept header for content negotiation */
166
public void setUseNotAcceptableStatusCode(boolean useNotAcceptableStatusCode);
167
}
168
```
169
170
**Usage Example:**
171
172
```java
173
@Configuration
174
public class ContentNegotiationConfig {
175
176
@Bean
177
public ContentNegotiatingViewResolver contentNegotiatingResolver() {
178
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
179
180
// Set up content negotiation
181
ContentNegotiationManager manager = new ContentNegotiationManager(
182
new HeaderContentNegotiationStrategy(),
183
new FixedContentNegotiationStrategy(MediaType.APPLICATION_JSON)
184
);
185
resolver.setContentNegotiationManager(manager);
186
187
// Add view resolvers
188
List<ViewResolver> viewResolvers = Arrays.asList(
189
new BeanNameViewResolver(),
190
jspViewResolver()
191
);
192
resolver.setViewResolvers(viewResolvers);
193
194
// Add default views
195
List<View> defaultViews = Arrays.asList(
196
new MappingJackson2JsonView()
197
);
198
resolver.setDefaultViews(defaultViews);
199
200
resolver.setOrder(1);
201
return resolver;
202
}
203
}
204
```
205
206
### Special View Types
207
208
#### RedirectView
209
210
View that redirects to an absolute, context relative, or current request relative URL.
211
212
```java { .api }
213
/**
214
* View that redirects to an absolute, context relative, or current request relative URL.
215
*/
216
public class RedirectView extends AbstractUrlBasedView implements SmartView {
217
218
/** Create redirect view with URL */
219
public RedirectView(String url);
220
221
/** Create redirect view with URL and context relative flag */
222
public RedirectView(String url, boolean contextRelative);
223
224
/** Create redirect view with URL, context relative flag, and HTTP 1.0 compatibility */
225
public RedirectView(String url, boolean contextRelative, boolean http10Compatible);
226
227
/** Set whether URL is relative to context path */
228
public void setContextRelative(boolean contextRelative);
229
230
/** Set HTTP 1.0 compatibility mode */
231
public void setHttp10Compatible(boolean http10Compatible);
232
233
/** Set whether to expose model attributes as query parameters */
234
public void setExposeModelAttributes(boolean exposeModelAttributes);
235
236
/** Set encoding for URL */
237
public void setEncodingScheme(String encodingScheme);
238
239
/** Set status code for redirect */
240
public void setStatusCode(HttpStatus statusCode);
241
242
/** Set whether to expand URI template variables */
243
public void setExpandUriTemplateVariables(boolean expandUriTemplateVariables);
244
245
/** Set hosts that redirects are allowed to */
246
public void setHosts(String... hosts);
247
}
248
```
249
250
**Usage Examples:**
251
252
```java
253
@Controller
254
public class UserController {
255
256
@PostMapping("/users")
257
public RedirectView createUser(@ModelAttribute User user) {
258
User savedUser = userService.save(user);
259
return new RedirectView("/users/" + savedUser.getId(), true);
260
}
261
262
@PostMapping("/users/{id}/activate")
263
public String activateUser(@PathVariable Long id, RedirectAttributes redirectAttributes) {
264
userService.activate(id);
265
redirectAttributes.addFlashAttribute("message", "User activated successfully");
266
return "redirect:/users/{id}";
267
}
268
}
269
270
@Configuration
271
public class ViewConfiguration {
272
273
@Bean
274
public RedirectView homeRedirect() {
275
RedirectView redirect = new RedirectView("/dashboard", true);
276
redirect.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
277
return redirect;
278
}
279
}
280
```
281
282
### Template Engine Integration
283
284
#### Thymeleaf Integration
285
286
```java
287
@Configuration
288
@EnableWebMvc
289
public class ThymeleafConfig {
290
291
@Bean
292
public SpringResourceTemplateResolver templateResolver() {
293
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
294
templateResolver.setApplicationContext(applicationContext);
295
templateResolver.setPrefix("/WEB-INF/templates/");
296
templateResolver.setSuffix(".html");
297
templateResolver.setTemplateMode(TemplateMode.HTML);
298
templateResolver.setCacheable(false); // For development
299
return templateResolver;
300
}
301
302
@Bean
303
public SpringTemplateEngine templateEngine() {
304
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
305
templateEngine.setTemplateResolver(templateResolver());
306
templateEngine.setEnableSpringELCompiler(true);
307
return templateEngine;
308
}
309
310
@Bean
311
public ThymeleafViewResolver viewResolver() {
312
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
313
viewResolver.setTemplateEngine(templateEngine());
314
viewResolver.setOrder(1);
315
return viewResolver;
316
}
317
}
318
```
319
320
#### FreeMarker Integration
321
322
```java
323
@Configuration
324
public class FreeMarkerConfig {
325
326
@Bean
327
public FreeMarkerConfigurer freeMarkerConfigurer() {
328
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
329
configurer.setTemplateLoaderPath("/WEB-INF/freemarker/");
330
configurer.setDefaultEncoding("UTF-8");
331
332
Properties settings = new Properties();
333
settings.put("template_update_delay", "0");
334
settings.put("default_encoding", "UTF-8");
335
settings.put("number_format", "0.######");
336
configurer.setFreemarkerSettings(settings);
337
338
return configurer;
339
}
340
341
@Bean
342
public FreeMarkerViewResolver freeMarkerViewResolver() {
343
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
344
resolver.setPrefix("");
345
resolver.setSuffix(".ftl");
346
resolver.setContentType("text/html;charset=UTF-8");
347
resolver.setOrder(2);
348
return resolver;
349
}
350
}
351
```
352
353
### JSON and XML Views
354
355
#### MappingJackson2JsonView
356
357
```java { .api }
358
/**
359
* Spring MVC View that renders JSON content by serializing the model for the current request using Jackson's ObjectMapper.
360
*/
361
public class MappingJackson2JsonView extends AbstractJackson2View {
362
363
/** Set the object mapper */
364
public void setObjectMapper(ObjectMapper objectMapper);
365
366
/** Set encoding */
367
public void setEncoding(Charset encoding);
368
369
/** Set whether to extract value from single key models */
370
public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel);
371
372
/** Set JSONP function name */
373
public void setJsonpParameterNames(Set<String> jsonpParameterNames);
374
375
/** Set prefix for JSON content */
376
public void setPrefixJson(boolean prefixJson);
377
}
378
```
379
380
#### MappingJackson2XmlView
381
382
```java { .api }
383
/**
384
* Spring MVC View that renders XML content by serializing the model for the current request using Jackson's XmlMapper.
385
*/
386
public class MappingJackson2XmlView extends AbstractJackson2View {
387
388
/** Set the XML mapper */
389
public void setObjectMapper(ObjectMapper objectMapper);
390
391
/** Set whether to extract value from single key models */
392
public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel);
393
}
394
```
395
396
**Usage Example:**
397
398
```java
399
@Configuration
400
public class JsonXmlViewConfig {
401
402
@Bean
403
public MappingJackson2JsonView jsonView() {
404
MappingJackson2JsonView view = new MappingJackson2JsonView();
405
view.setExtractValueFromSingleKeyModel(true);
406
407
ObjectMapper mapper = new ObjectMapper();
408
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
409
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
410
view.setObjectMapper(mapper);
411
412
return view;
413
}
414
415
@Bean
416
public MappingJackson2XmlView xmlView() {
417
MappingJackson2XmlView view = new MappingJackson2XmlView();
418
view.setExtractValueFromSingleKeyModel(true);
419
420
XmlMapper xmlMapper = new XmlMapper();
421
xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
422
view.setObjectMapper(xmlMapper);
423
424
return view;
425
}
426
}
427
```
428
429
### View Resolution Configuration
430
431
```java
432
@Configuration
433
@EnableWebMvc
434
public class ViewResolutionConfig implements WebMvcConfigurer {
435
436
@Override
437
public void configureViewResolvers(ViewResolverRegistry registry) {
438
// Configure JSP resolver
439
registry.jsp("/WEB-INF/views/", ".jsp");
440
441
// Configure Thymeleaf (if available)
442
registry.enableContentNegotiation(new MappingJackson2JsonView());
443
444
// Configure FreeMarker
445
registry.freeMarker().prefix("/WEB-INF/freemarker/").suffix(".ftl");
446
}
447
448
@Bean
449
public ViewResolverComposite viewResolver() {
450
ViewResolverComposite composite = new ViewResolverComposite();
451
452
List<ViewResolver> resolvers = Arrays.asList(
453
contentNegotiatingViewResolver(),
454
new BeanNameViewResolver(),
455
jspViewResolver(),
456
thymeleafViewResolver()
457
);
458
459
composite.setViewResolvers(resolvers);
460
return composite;
461
}
462
}
463
```