web-portlet.adoc 60.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468
[[portlet]]
= Portlet MVC Framework


[[portlet-introduction]]
== Introduction

.JSR-168 The Java Portlet Specification
****
For more general information about portlet development, please review a whitepaper from
Oracle entitled
http://www.oracle.com/technetwork/java/index-raji-test-141933.html["Introduction
to JSR 168"], and of course the
http://jcp.org/aboutJava/communityprocess/final/jsr168/[JSR-168 Specification] itself.
****

In addition to supporting conventional (servlet-based) Web development, Spring also
supports JSR-168 Portlet development. As much as possible, the Portlet MVC framework is
a mirror image of the Web MVC framework, and also uses the same underlying view
abstractions and integration technology. So, be sure to review the chapters entitled
<<mvc>> and <<view>> before continuing with this chapter.

[NOTE]
====
Bear in mind that while the concepts of Spring MVC are the same in Spring Portlet MVC,
there are some notable differences created by the unique workflow of JSR-168 portlets.
====

The main way in which portlet workflow differs from servlet workflow is that the request
to the portlet can have two distinct phases: the action phase and the render phase. The
action phase is executed only once and is where any 'backend' changes or actions occur,
such as making changes in a database. The render phase then produces what is displayed
to the user each time the display is refreshed. The critical point here is that for a
single overall request, the action phase is executed only once, but the render phase may
be executed multiple times. This provides (and requires) a clean separation between the
activities that modify the persistent state of your system and the activities that
generate what is displayed to the user.

.Spring Web Flow
****
Spring Web Flow (SWF) aims to be the best solution for the management of web application
page flow.

SWF integrates with existing frameworks like Spring MVC and JSF, in both Servlet and
Portlet environments. If you have a business process (or processes) that would benefit
from a conversational model as opposed to a purely request model, then SWF may be the
solution.

SWF allows you to capture logical page flows as self-contained modules that are reusable
in different situations, and as such is ideal for building web application modules that
guide the user through controlled navigations that drive business processes.

For more information about SWF, consult the Spring Web Flow website.
****

The dual phases of portlet requests are one of the real strengths of the JSR-168
specification. For example, dynamic search results can be updated routinely on the
display without the user explicitly rerunning the search. Most other portlet MVC
frameworks attempt to completely hide the two phases from the developer and make it look
as much like traditional servlet development as possible - we think this approach
removes one of the main benefits of using portlets. So, the separation of the two phases
is preserved throughout the Spring Portlet MVC framework. The primary manifestation of
this approach is that where the servlet version of the MVC classes will have one method
that deals with the request, the portlet version of the MVC classes will have two
methods that deal with the request: one for the action phase and one for the render
phase. For example, where the servlet version of `AbstractController` has the
`handleRequestInternal(..)` method, the portlet version of `AbstractController` has
`handleActionRequestInternal(..)` and `handleRenderRequestInternal(..)` methods.

The framework is designed around a `DispatcherPortlet` that dispatches requests to
handlers, with configurable handler mappings and view resolution, just as the
`DispatcherServlet` in the web framework does. File upload is also supported in the same
way.

Locale resolution and theme resolution are not supported in Portlet MVC - these areas
are in the purview of the portal/portlet container and are not appropriate at the Spring
level. However, all mechanisms in Spring that depend on the locale (such as
internationalization of messages) will still function properly because
`DispatcherPortlet` exposes the current locale in the same way as `DispatcherServlet`.



[[portlet-introduction-controller]]
=== Controllers - The C in MVC
The default handler is still a very simple `Controller` interface, offering just two
methods:

* `void handleActionRequest(request,response)`
* `ModelAndView handleRenderRequest(request,response)`

The framework also includes most of the same controller implementation hierarchy, such
as `AbstractController`, `SimpleFormController`, and so on. Data binding, command object
usage, model handling, and view resolution are all the same as in the servlet framework.



[[portlet-introduction-view]]
=== Views - The V in MVC
All the view rendering capabilities of the servlet framework are used directly via a
special bridge servlet named `ViewRendererServlet`. By using this servlet, the portlet
request is converted into a servlet request and the view can be rendered using the
entire normal servlet infrastructure. This means all the existing renderers, such as
JSP, Velocity, etc., can still be used within the portlet.



[[portlet-introduction-scope]]
=== Web-scoped beans
Spring Portlet MVC supports beans whose lifecycle is scoped to the current HTTP request
or HTTP `Session` (both normal and global). This is not a specific feature of Spring
Portlet MVC itself, but rather of the `WebApplicationContext` container(s) that Spring
Portlet MVC uses. These bean scopes are described in detail in
<<beans-factory-scopes-other>>




[[portlet-dispatcher]]
== The DispatcherPortlet

Portlet MVC is a request-driven web MVC framework, designed around a portlet that
dispatches requests to controllers and offers other functionality facilitating the
development of portlet applications. Spring's `DispatcherPortlet` however, does more
than just that. It is completely integrated with the Spring `ApplicationContext` and
allows you to use every other feature Spring has.

Like ordinary portlets, the `DispatcherPortlet` is declared in the `portlet.xml` file of
your web application:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<portlet>
		<portlet-name>sample</portlet-name>
		<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>view</portlet-mode>
		</supports>
		<portlet-info>
			<title>Sample Portlet</title>
		</portlet-info>
	</portlet>
----

The `DispatcherPortlet` now needs to be configured.

In the Portlet MVC framework, each `DispatcherPortlet` has its own
`WebApplicationContext`, which inherits all the beans already defined in the Root
`WebApplicationContext`. These inherited beans can be overridden in the portlet-specific
scope, and new scope-specific beans can be defined local to a given portlet instance.

The framework will, on initialization of a `DispatcherPortlet`, look for a file named
`[portlet-name]-portlet.xml` in the `WEB-INF` directory of your web application and
create the beans defined there (overriding the definitions of any beans defined with the
same name in the global scope).

The config location used by the `DispatcherPortlet` can be modified through a portlet
initialization parameter (see below for details).

The Spring `DispatcherPortlet` has a few special beans it uses, in order to be able to
process requests and render the appropriate views. These beans are included in the
Spring framework and can be configured in the `WebApplicationContext`, just as any other
bean would be configured. Each of those beans is described in more detail below. Right
now, we'll just mention them, just to let you know they exist and to enable us to go on
talking about the `DispatcherPortlet`. For most of the beans, defaults are provided so
you don't have to worry about configuring them.

[[portlet-webappctx-special-beans-tbl]]
.Special beans in the WebApplicationContext
[cols="1,4"]
|===
| Expression| Explanation

| handler mapping(s)
| (<<portlet-handlermapping>>) a list of pre- and post-processors and controllers that
  will be executed if they match certain criteria (for instance a matching portlet mode
  specified with the controller)

| controller(s)
| (<<portlet-controller>>) the beans providing the actual functionality (or at least,
  access to the functionality) as part of the MVC triad

| view resolver
| (<<portlet-viewresolver>>) capable of resolving view names to view definitions

| multipart resolver
| (<<portlet-multipart>>) offers functionality to process file uploads from HTML forms

| handler exception resolver
| (<<portlet-exceptionresolver>>) offers functionality to map exceptions to views or
  implement other more complex exception handling code
|===

When a `DispatcherPortlet` is setup for use and a request comes in for that specific
`DispatcherPortlet`, it starts processing the request. The list below describes the
complete process a request goes through if handled by a `DispatcherPortlet`:

. The locale returned by `PortletRequest.getLocale()` is bound to the request to let
elements in the process resolve the locale to use when processing the request (rendering
the view, preparing data, etc.).
. If a multipart resolver is specified and this is an `ActionRequest`, the request is
inspected for multiparts and if they are found, it is wrapped in a
`MultipartActionRequest` for further processing by other elements in the process. (See
<<portlet-multipart>> for further information about multipart handling).
. An appropriate handler is searched for. If a handler is found, the execution chain
associated with the handler (pre-processors, post-processors, controllers) will be
executed in order to prepare a model.
. If a model is returned, the view is rendered, using the view resolver that has been
configured with the `WebApplicationContext`. If no model is returned (which could be due
to a pre- or post-processor intercepting the request, for example, for security
reasons), no view is rendered, since the request could already have been fulfilled.

Exceptions that are thrown during processing of the request get picked up by any of the
handler exception resolvers that are declared in the `WebApplicationContext`. Using
these exception resolvers you can define custom behavior in case such exceptions get
thrown.

You can customize Spring's `DispatcherPortlet` by adding context parameters in the
`portlet.xml` file or portlet init-parameters. The possibilities are listed below.

[[portlet-dpp-init-params]]
.DispatcherPortlet initialization parameters
[cols="1,4"]
|===
| Parameter| Explanation

| `contextClass`
| Class that implements `WebApplicationContext`, which will be used to instantiate the
  context used by this portlet. If this parameter isn't specified, the
  `XmlPortletApplicationContext` will be used.

| `contextConfigLocation`
| String which is passed to the context instance (specified by `contextClass`) to
  indicate where context(s) can be found. The String is potentially split up into
  multiple Strings (using a comma as a delimiter) to support multiple contexts (in case
  of multiple context locations, for beans that are defined twice, the latest takes
  precedence).

| `namespace`
| The namespace of the `WebApplicationContext`. Defaults to `[portlet-name]-portlet`.

| `viewRendererUrl`
| The URL at which `DispatcherPortlet` can access an instance of `ViewRendererServlet`
  (see <<portlet-viewservlet>>).
|===




[[portlet-viewservlet]]
== The ViewRendererServlet

The rendering process in Portlet MVC is a bit more complex than in Web MVC. In order to
reuse all the <<view,view technologies>> from Spring Web MVC, we must convert the
`PortletRequest` / `PortletResponse` to `HttpServletRequest` / `HttpServletResponse` and
then call the `render` method of the `View`. To do this, `DispatcherPortlet` uses a
special servlet that exists for just this purpose: the `ViewRendererServlet`.

In order for `DispatcherPortlet` rendering to work, you must declare an instance of the
`ViewRendererServlet` in the `web.xml` file for your web application as follows:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<servlet>
		<servlet-name>ViewRendererServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>ViewRendererServlet</servlet-name>
		<url-pattern>/WEB-INF/servlet/view</url-pattern>
	</servlet-mapping>
----

To perform the actual rendering, `DispatcherPortlet` does the following:

. Binds the `WebApplicationContext` to the request as an attribute under the same
`WEB_APPLICATION_CONTEXT_ATTRIBUTE` key that `DispatcherServlet` uses.
. Binds the `Model` and `View` objects to the request to make them available to the
`ViewRendererServlet`.
. Constructs a `PortletRequestDispatcher` and performs an `include` using the `/WEB-
INF/servlet/view` URL that is mapped to the `ViewRendererServlet`.

The `ViewRendererServlet` is then able to call the `render` method on the `View` with
the appropriate arguments.

The actual URL for the `ViewRendererServlet` can be changed using `DispatcherPortlet`'s
`viewRendererUrl` configuration parameter.




[[portlet-controller]]
== Controllers
The controllers in Portlet MVC are very similar to the Web MVC Controllers, and porting
code from one to the other should be simple.

The basis for the Portlet MVC controller architecture is the
`org.springframework.web.portlet.mvc.Controller` interface, which is listed below.

[source,java,indent=0]
----
	public interface Controller {

		/**
		 * Process the render request and return a ModelAndView object which the
		 * DispatcherPortlet will render.
		 */
		ModelAndView handleRenderRequest(RenderRequest request,
				RenderResponse response) throws Exception;

		/**
		 * Process the action request. There is nothing to return.
		 */
		void handleActionRequest(ActionRequest request,
				ActionResponse response) throws Exception;

	}
----

As you can see, the Portlet `Controller` interface requires two methods that handle the
two phases of a portlet request: the action request and the render request. The action
phase should be capable of handling an action request, and the render phase should be
capable of handling a render request and returning an appropriate model and view. While
the `Controller` interface is quite abstract, Spring Portlet MVC offers several
controllers that already contain a lot of the functionality you might need; most of
these are very similar to controllers from Spring Web MVC. The `Controller` interface
just defines the most common functionality required of every controller: handling an
action request, handling a render request, and returning a model and a view.



[[portlet-controller-abstractcontroller]]
=== AbstractController and PortletContentGenerator

Of course, just a `Controller` interface isn't enough. To provide a basic
infrastructure, all of Spring Portlet MVC's ++Controller++s inherit from
`AbstractController`, a class offering access to Spring's `ApplicationContext` and
control over caching.

[[portlet-ac-features]]
.Features offered by the AbstractController
[cols="1,4"]
|===
| Parameter| Explanation

| `requireSession`
| Indicates whether or not this `Controller` requires a session to do its work. This
  feature is offered to all controllers. If a session is not present when such a
  controller receives a request, the user is informed using a `SessionRequiredException`.

| `synchronizeSession`
| Use this if you want handling by this controller to be synchronized on the user's
  session. To be more specific, the extending controller will override the
  `handleRenderRequestInternal(..)` and `handleActionRequestInternal(..)` methods, which
  will be synchronized on the user's session if you specify this variable.

| `renderWhenMinimized`
| If you want your controller to actually render the view when the portlet is in a
  minimized state, set this to true. By default, this is set to false so that portlets
  that are in a minimized state don't display any content.

| `cacheSeconds`
| When you want a controller to override the default cache expiration defined for the
  portlet, specify a positive integer here. By default it is set to `-1`, which does not
  change the default caching. Setting it to `0` will ensure the result is never cached.
|===

The `requireSession` and `cacheSeconds` properties are declared on the
`PortletContentGenerator` class, which is the superclass of `AbstractController`) but
are included here for completeness.

When using the `AbstractController` as a base class for your controllers (which is not
recommended since there are a lot of other controllers that might already do the job for
you) you only have to override either the `handleActionRequestInternal(ActionRequest,
ActionResponse)` method or the `handleRenderRequestInternal(RenderRequest,
RenderResponse)` method (or both), implement your logic, and return a `ModelAndView`
object (in the case of `handleRenderRequestInternal`).

The default implementations of both `handleActionRequestInternal(..)` and
`handleRenderRequestInternal(..)` throw a `PortletException`. This is consistent with
the behavior of `GenericPortlet` from the JSR- 168 Specification API. So you only need
to override the method that your controller is intended to handle.

Here is short example consisting of a class and a declaration in the web application
context.

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	package samples;

	import javax.portlet.RenderRequest;
	import javax.portlet.RenderResponse;

	import org.springframework.web.portlet.mvc.AbstractController;
	import org.springframework.web.portlet.ModelAndView;

	public class SampleController extends AbstractController {

		public ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) {
			ModelAndView mav = new ModelAndView("foo");
			mav.addObject("message", "Hello World!");
			return mav;
		}

	}
----

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<bean id="sampleController" class="samples.SampleController">
		<property name="cacheSeconds" value="120"/>
	</bean>
----

The class above and the declaration in the web application context is all you need
besides setting up a handler mapping (see <<portlet-handlermapping>>) to get this very
simple controller working.



[[portlet-controller-simple]]
=== Other simple controllers
Although you can extend `AbstractController`, Spring Portlet MVC provides a number of
concrete implementations which offer functionality that is commonly used in simple MVC
applications.

The `ParameterizableViewController` is basically the same as the example above, except
for the fact that you can specify the view name that it will return in the web
application context (no need to hard-code the view name).

The `PortletModeNameViewController` uses the current mode of the portlet as the view
name. So, if your portlet is in View mode (i.e. `PortletMode.VIEW`) then it uses "view"
as the view name.



[[portlet-controller-command]]
=== Command Controllers
Spring Portlet MVC has the exact same hierarchy of __command controllers__ as Spring Web
MVC. They provide a way to interact with data objects and dynamically bind parameters
from the `PortletRequest` to the data object specified. Your data objects don't have to
implement a framework-specific interface, so you can directly manipulate your persistent
objects if you desire. Let's examine what command controllers are available, to get an
overview of what you can do with them:

* `AbstractCommandController` - a command controller you can use to create your own
  command controller, capable of binding request parameters to a data object you
  specify. This class does not offer form functionality, it does however offer
  validation features and lets you specify in the controller itself what to do with the
  command object that has been filled with the parameters from the request.
* `AbstractFormController` - an abstract controller offering form submission support.
  Using this controller you can model forms and populate them using a command object you
  retrieve in the controller. After a user has filled the form, `AbstractFormController`
  binds the fields, validates, and hands the object back to the controller to take
  appropriate action. Supported features are: invalid form submission (resubmission),
  validation, and normal form workflow. You implement methods to determine which views
  are used for form presentation and success. Use this controller if you need forms, but
  don't want to specify what views you're going to show the user in the application
  context.
* `SimpleFormController` - a concrete `AbstractFormController` that provides even more
  support when creating a form with a corresponding command object. The
  `SimpleFormController` lets you specify a command object, a viewname for the form, a
  viewname for the page you want to show the user when form submission has succeeded,
  and more.
* `AbstractWizardFormController` -- a concrete `AbstractFormController` that provides a
  wizard-style interface for editing the contents of a command object across multiple
  display pages. Supports multiple user actions: finish, cancel, or page change, all of
  which are easily specified in request parameters from the view.

These command controllers are quite powerful, but they do require a detailed
understanding of how they operate in order to use them efficiently. Carefully review the
javadocs for this entire hierarchy and then look at some sample implementations before
you start using them.



[[portlet-controller-wrapping]]
=== PortletWrappingController

Instead of developing new controllers, it is possible to use existing portlets and map
requests to them from a `DispatcherPortlet`. Using the `PortletWrappingController`, you
can instantiate an existing `Portlet` as a `Controller` as follows:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<bean id="myPortlet" class="org.springframework.web.portlet.mvc.PortletWrappingController">
		<property name="portletClass" value="sample.MyPortlet"/>
		<property name="portletName" value="my-portlet"/>
		<property name="initParameters">
			<value>config=/WEB-INF/my-portlet-config.xml</value>
		</property>
	</bean>
----

This can be very valuable since you can then use interceptors to pre-process and
post-process requests going to these portlets. Since JSR-168 does not support any kind
of filter mechanism, this is quite handy. For example, this can be used to wrap the
Hibernate `OpenSessionInViewInterceptor` around a MyFaces JSF Portlet.




[[portlet-handlermapping]]
== Handler mappings
Using a handler mapping you can map incoming portlet requests to appropriate handlers.
There are some handler mappings you can use out of the box, for example, the
`PortletModeHandlerMapping`, but let's first examine the general concept of a
`HandlerMapping`.

Note: We are intentionally using the term "Handler" here instead of "Controller".
`DispatcherPortlet` is designed to be used with other ways to process requests than just
Spring Portlet MVC's own Controllers. A Handler is any Object that can handle portlet
requests. Controllers are an example of Handlers, and they are of course the default. To
use some other framework with `DispatcherPortlet`, a corresponding implementation of
`HandlerAdapter` is all that is needed.

The functionality a basic `HandlerMapping` provides is the delivering of a
`HandlerExecutionChain`, which must contain the handler that matches the incoming
request, and may also contain a list of handler interceptors that are applied to the
request. When a request comes in, the `DispatcherPortlet` will hand it over to the
handler mapping to let it inspect the request and come up with an appropriate
`HandlerExecutionChain`. Then the `DispatcherPortlet` will execute the handler and
interceptors in the chain (if any). These concepts are all exactly the same as in Spring
Web MVC.

The concept of configurable handler mappings that can optionally contain interceptors
(executed before or after the actual handler was executed, or both) is extremely
powerful. A lot of supporting functionality can be built into a custom `HandlerMapping`.
Think of a custom handler mapping that chooses a handler not only based on the portlet
mode of the request coming in, but also on a specific state of the session associated
with the request.

In Spring Web MVC, handler mappings are commonly based on URLs. Since there is really no
such thing as a URL within a Portlet, we must use other mechanisms to control mappings.
The two most common are the portlet mode and a request parameter, but anything available
to the portlet request can be used in a custom handler mapping.

The rest of this section describes three of Spring Portlet MVC's most commonly used
handler mappings. They all extend `AbstractHandlerMapping` and share the following
properties:

* `interceptors`: The list of interceptors to use. ++HandlerInterceptor++s are discussed
  in <<portlet-handlermapping-interceptor>>.
* `defaultHandler`: The default handler to use, when this handler mapping does not
  result in a matching handler.
* `order`: Based on the value of the order property (see the
  `org.springframework.core.Ordered` interface), Spring will sort all handler mappings
  available in the context and apply the first matching handler.
* `lazyInitHandlers`: Allows for lazy initialization of singleton handlers (prototype
  handlers are always lazily initialized). Default value is false. This property is
  directly implemented in the three concrete Handlers.



[[portlet-handlermapping-portletmode]]
=== PortletModeHandlerMapping

This is a simple handler mapping that maps incoming requests based on the current mode
of the portlet (e.g. 'view', 'edit', 'help'). An example:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<bean class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
		<property name="portletModeMap">
			<map>
				<entry key="view" value-ref="viewHandler"/>
				<entry key="edit" value-ref="editHandler"/>
				<entry key="help" value-ref="helpHandler"/>
			</map>
		</property>
	</bean>
----



[[portlet-handlermapping-parameter]]
=== ParameterHandlerMapping

If we need to navigate around to multiple controllers without changing portlet mode, the
simplest way to do this is with a request parameter that is used as the key to control
the mapping.

`ParameterHandlerMapping` uses the value of a specific request parameter to control the
mapping. The default name of the parameter is `'action'`, but can be changed using the
`'parameterName'` property.

The bean configuration for this mapping will look something like this:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<bean class="org.springframework.web.portlet.handler.ParameterHandlerMapping">
		<property name="parameterMap">
			<map>
				<entry key="add" value-ref="addItemHandler"/>
				<entry key="edit" value-ref="editItemHandler"/>
				<entry key="delete" value-ref="deleteItemHandler"/>
			</map>
		</property>
	</bean>
----



[[portlet-handlermapping-portletmodeparameter]]
=== PortletModeParameterHandlerMapping

The most powerful built-in handler mapping, `PortletModeParameterHandlerMapping`
combines the capabilities of the two previous ones to allow different navigation within
each portlet mode.

Again the default name of the parameter is "action", but can be changed using the
`parameterName` property.

By default, the same parameter value may not be used in two different portlet modes.
This is so that if the portal itself changes the portlet mode, the request will no
longer be valid in the mapping. This behavior can be changed by setting the
`allowDupParameters` property to true. However, this is not recommended.

The bean configuration for this mapping will look something like this:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<bean class="org.springframework.web.portlet.handler.PortletModeParameterHandlerMapping">
		<property name="portletModeParameterMap">
			<map>
				<entry key="view"> <!-- 'view' portlet mode -->
					<map>
						<entry key="add" value-ref="addItemHandler"/>
						<entry key="edit" value-ref="editItemHandler"/>
						<entry key="delete" value-ref="deleteItemHandler"/>
					</map>
				</entry>
				<entry key="edit"> <!-- 'edit' portlet mode -->
					<map>
						<entry key="prefs" value-ref="prefsHandler"/>
						<entry key="resetPrefs" value-ref="resetPrefsHandler"/>
					</map>
				</entry>
			</map>
		</property>
	</bean>
----

This mapping can be chained ahead of a `PortletModeHandlerMapping`, which can then
provide defaults for each mode and an overall default as well.



[[portlet-handlermapping-interceptor]]
=== Adding HandlerInterceptors

Spring's handler mapping mechanism has a notion of handler interceptors, which can be
extremely useful when you want to apply specific functionality to certain requests, for
example, checking for a principal. Again Spring Portlet MVC implements these concepts in
the same way as Web MVC.

Interceptors located in the handler mapping must implement `HandlerInterceptor` from the
`org.springframework.web.portlet` package. Just like the servlet version, this interface
defines three methods: one that will be called before the actual handler will be
executed ( `preHandle`), one that will be called after the handler is executed (
`postHandle`), and one that is called after the complete request has finished (
`afterCompletion`). These three methods should provide enough flexibility to do all
kinds of pre- and post- processing.

The `preHandle` method returns a boolean value. You can use this method to break or
continue the processing of the execution chain. When this method returns `true`, the
handler execution chain will continue. When it returns `false`, the `DispatcherPortlet`
assumes the interceptor itself has taken care of requests (and, for example, rendered an
appropriate view) and does not continue executing the other interceptors and the actual
handler in the execution chain.

The `postHandle` method is only called on a `RenderRequest`. The `preHandle` and
`afterCompletion` methods are called on both an `ActionRequest` and a `RenderRequest`.
If you need to execute logic in these methods for just one type of request, be sure to
check what kind of request it is before processing it.



[[portlet-handlermapping-interceptoradapter]]
=== HandlerInterceptorAdapter

As with the servlet package, the portlet package has a concrete implementation of
`HandlerInterceptor` called `HandlerInterceptorAdapter`. This class has empty versions
of all the methods so that you can inherit from this class and implement just one or two
methods when that is all you need.



[[portlet-handlermapping-parameterinterceptor]]
=== ParameterMappingInterceptor

The portlet package also has a concrete interceptor named `ParameterMappingInterceptor`
that is meant to be used directly with `ParameterHandlerMapping` and
`PortletModeParameterHandlerMapping`. This interceptor will cause the parameter that is
being used to control the mapping to be forwarded from an `ActionRequest` to the
subsequent `RenderRequest`. This will help ensure that the `RenderRequest` is mapped to
the same Handler as the `ActionRequest`. This is done in the `preHandle` method of the
interceptor, so you can still modify the parameter value in your handler to change where
the `RenderRequest` will be mapped.

Be aware that this interceptor is calling `setRenderParameter` on the `ActionResponse`,
which means that you cannot call `sendRedirect` in your handler when using this
interceptor. If you need to do external redirects then you will either need to forward
the mapping parameter manually or write a different interceptor to handle this for you.




[[portlet-viewresolver]]
== Views and resolving them
As mentioned previously, Spring Portlet MVC directly reuses all the view technologies
from Spring Web MVC. This includes not only the various `View` implementations
themselves, but also the `ViewResolver` implementations. For more information, refer to
<<view>> and <<mvc-viewresolver>> respectively.

A few items on using the existing `View` and `ViewResolver` implementations are worth
mentioning:

* Most portals expect the result of rendering a portlet to be an HTML fragment. So,
  things like JSP/JSTL, Velocity, FreeMarker, and XSLT all make sense. But it is
  unlikely that views that return other document types will make any sense in a portlet
  context.
* There is no such thing as an HTTP redirect from within a portlet (the
  `sendRedirect(..)` method of `ActionResponse` cannot be used to stay within the
  portal). So, `RedirectView` and use of the `'redirect:'` prefix will __not__ work
  correctly from within Portlet MVC.
* It may be possible to use the `'forward:'` prefix from within Portlet MVC. However,
  remember that since you are in a portlet, you have no idea what the current URL looks
  like. This means you cannot use a relative URL to access other resources in your web
  application and that you will have to use an absolute URL.

Also, for JSP development, the new Spring Taglib and the new Spring Form Taglib both
work in portlet views in exactly the same way that they work in servlet views.




[[portlet-multipart]]
== Multipart (file upload) support
Spring Portlet MVC has built-in multipart support to handle file uploads in portlet
applications, just like Web MVC does. The design for the multipart support is done with
pluggable `PortletMultipartResolver` objects, defined in the
`org.springframework.web.portlet.multipart` package. Spring provides a
`PortletMultipartResolver` for use with
http://jakarta.apache.org/commons/fileupload[Commons FileUpload]. How uploading files is
supported will be described in the rest of this section.

By default, no multipart handling will be done by Spring Portlet MVC, as some developers
will want to handle multiparts themselves. You will have to enable it yourself by adding
a multipart resolver to the web application's context. After you have done that,
`DispatcherPortlet` will inspect each request to see if it contains a multipart. If no
multipart is found, the request will continue as expected. However, if a multipart is
found in the request, the `PortletMultipartResolver` that has been declared in your
context will be used. After that, the multipart attribute in your request will be
treated like any other attribute.

[NOTE]
====
Any configured `PortletMultipartResolver` bean __must__ have the following id (or name):
" `portletMultipartResolver`". If you have defined your `PortletMultipartResolver` with
any other name, then the `DispatcherPortlet` will __not__ find your
`PortletMultipartResolver`, and consequently no multipart support will be in effect.
====



[[portlet-multipart-resolver]]
=== Using the PortletMultipartResolver

The following example shows how to use the `CommonsPortletMultipartResolver`:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<bean id="portletMultipartResolver"
			class="org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver">
		<!-- one of the properties available; the maximum file size in bytes -->
		<property name="maxUploadSize" value="100000"/>
	</bean>
----

Of course you also need to put the appropriate jars in your classpath for the multipart
resolver to work. In the case of the `CommonsMultipartResolver`, you need to use
`commons-fileupload.jar`. Be sure to use at least version 1.1 of Commons FileUpload as
previous versions do not support JSR-168 Portlet applications.

Now that you have seen how to set Portlet MVC up to handle multipart requests, let's
talk about how to actually use it. When `DispatcherPortlet` detects a multipart request,
it activates the resolver that has been declared in your context and hands over the
request. What the resolver then does is wrap the current `ActionRequest` in a
`MultipartActionRequest` that has support for multipart file uploads. Using the
`MultipartActionRequest` you can get information about the multiparts contained by this
request and actually get access to the multipart files themselves in your controllers.

Note that you can only receive multipart file uploads as part of an `ActionRequest`, not
as part of a `RenderRequest`.



[[portlet-multipart-forms]]
=== Handling a file upload in a form
After the `PortletMultipartResolver` has finished doing its job, the request will be
processed like any other. To use the `PortletMultipartResolver`, create a form with an
upload field (see example below), then let Spring bind the file onto your form (backing
object). To actually let the user upload a file, we have to create a (JSP/HTML) form:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<h1>Please upload a file</h1>
	<form method="post" action="<portlet:actionURL/>" enctype="multipart/form-data">
		<input type="file" name="file"/>
		<input type="submit"/>
	</form>
----

As you can see, we've created a field named "file" that matches the property of the bean
that holds the `byte[]` array. Furthermore we've added the encoding attribute (
`enctype="multipart/form-data"`), which is necessary to let the browser know how to
encode the multipart fields (do not forget this!).

Just as with any other property that's not automagically convertible to a string or
primitive type, to be able to put binary data in your objects you have to register a
custom editor with the `PortletRequestDataBinder`. There are a couple of editors
available for handling files and setting the results on an object. There's a
`StringMultipartFileEditor` capable of converting files to Strings (using a user-defined
character set), and there is a `ByteArrayMultipartFileEditor` which converts files to
byte arrays. They function analogous to the `CustomDateEditor`.

So, to be able to upload files using a form, declare the resolver, a mapping to a
controller that will process the bean, and the controller itself.

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<bean id="portletMultipartResolver"
			class="org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver"/>

	<bean class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
		<property name="portletModeMap">
			<map>
				<entry key="view" value-ref="fileUploadController"/>
			</map>
		</property>
	</bean>

	<bean id="fileUploadController" class="examples.FileUploadController">
		<property name="commandClass" value="examples.FileUploadBean"/>
		<property name="formView" value="fileuploadform"/>
		<property name="successView" value="confirmation"/>
	</bean>
----

After that, create the controller and the actual class to hold the file property.

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	public class FileUploadController extends SimpleFormController {

		public void onSubmitAction(ActionRequest request, ActionResponse response,
				Object command, BindException errors) throws Exception {

			// cast the bean
			FileUploadBean bean = (FileUploadBean) command;

			// let's see if there's content there
			byte[] file = bean.getFile();
			if (file == null) {
				// hmm, that's strange, the user did not upload anything
			}

			// do something with the file here
		}

		protected void initBinder(PortletRequest request,
				PortletRequestDataBinder binder) throws Exception {
			// to actually be able to convert Multipart instance to byte[]
			// we have to register a custom editor
			binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
			// now Spring knows how to handle multipart object and convert
		}

	}

	public class FileUploadBean {

		private byte[] file;

		public void setFile(byte[] file) {
			this.file = file;
		}

		public byte[] getFile() {
			return file;
		}

	}
----

As you can see, the `FileUploadBean` has a property of type `byte[]` that holds the
file. The controller registers a custom editor to let Spring know how to actually
convert the multipart objects the resolver has found to properties specified by the
bean. In this example, nothing is done with the `byte[]` property of the bean itself,
but in practice you can do whatever you want (save it in a database, mail it to
somebody, etc).

An equivalent example in which a file is bound straight to a String-typed property on a
form backing object might look like this:

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	public class FileUploadController extends SimpleFormController {

		public void onSubmitAction(ActionRequest request, ActionResponse response,
				Object command, BindException errors) throws Exception {

			// cast the bean
			FileUploadBean bean = (FileUploadBean) command;

			// let's see if there's content there
			String file = bean.getFile();
			if (file == null) {
				// hmm, that's strange, the user did not upload anything
			}

			// do something with the file here
		}

		protected void initBinder(PortletRequest request,
				PortletRequestDataBinder binder) throws Exception {

			// to actually be able to convert Multipart instance to a String
			// we have to register a custom editor
			binder.registerCustomEditor(String.class, new StringMultipartFileEditor());
			// now Spring knows how to handle multipart objects and convert
		}
	}

	public class FileUploadBean {

		private String file;

		public void setFile(String file) {
			this.file = file;
		}

		public String getFile() {
			return file;
		}
	}
----

Of course, this last example only makes (logical) sense in the context of uploading a
plain text file (it wouldn't work so well in the case of uploading an image file).

The third (and final) option is where one binds directly to a `MultipartFile` property
declared on the (form backing) object's class. In this case one does not need to
register any custom property editor because there is no type conversion to be performed.

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	public class FileUploadController extends SimpleFormController {

		public void onSubmitAction(ActionRequest request, ActionResponse response,
				Object command, BindException errors) throws Exception {

			// cast the bean
			FileUploadBean bean = (FileUploadBean) command;

			// let's see if there's content there
			MultipartFile file = bean.getFile();
			if (file == null) {
				// hmm, that's strange, the user did not upload anything
			}

			// do something with the file here
		}
	}

	public class FileUploadBean {

		private MultipartFile file;

		public void setFile(MultipartFile file) {
			this.file = file;
		}

		public MultipartFile getFile() {
			return file;
		}

	}
----




[[portlet-exceptionresolver]]
== Handling exceptions
Just like Servlet MVC, Portlet MVC provides ++HandlerExceptionResolver++s to ease the
pain of unexpected exceptions that occur while your request is being processed by a
handler that matched the request. Portlet MVC also provides a portlet-specific, concrete
`SimpleMappingExceptionResolver` that enables you to take the class name of any
exception that might be thrown and map it to a view name.




[[portlet-annotation]]
== Annotation-based controller configuration
Spring 2.5 introduced an annotation-based programming model for MVC controllers, using
annotations such as `@RequestMapping`, `@RequestParam`, `@ModelAttribute`, etc. This
annotation support is available for both Servlet MVC and Portlet MVC. Controllers
implemented in this style do not have to extend specific base classes or implement
specific interfaces. Furthermore, they do not usually have direct dependencies on
Servlet or Portlet API's, although they can easily get access to Servlet or Portlet
facilities if desired.

The following sections document these annotations and how they are most commonly used in
a Portlet environment.



[[portlet-ann-setup]]
=== Setting up the dispatcher for annotation support
__`@RequestMapping` will only be processed if a corresponding `HandlerMapping` (for
type level annotations) and/or `HandlerAdapter` (for method level annotations) is
present in the dispatcher.__ This is the case by default in both `DispatcherServlet` and
`DispatcherPortlet`.

However, if you are defining custom `HandlerMappings` or `HandlerAdapters`, then you
need to make sure that a corresponding custom `DefaultAnnotationHandlerMapping` and/or
`AnnotationMethodHandlerAdapter` is defined as well - provided that you intend to use
`@RequestMapping`.

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans.xsd">

		<bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

		<bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

		// ... (controller bean definitions) ...

	</beans>
----

Defining a `DefaultAnnotationHandlerMapping` and/or `AnnotationMethodHandlerAdapter`
explicitly also makes sense if you would like to customize the mapping strategy, e.g.
specifying a custom `WebBindingInitializer` (see below).



[[portlet-ann-controller]]
=== Defining a controller with @Controller

The `@Controller` annotation indicates that a particular class serves the role of a
__controller__. There is no need to extend any controller base class or reference the
Portlet API. You are of course still able to reference Portlet-specific features if you
need to.

The basic purpose of the `@Controller` annotation is to act as a stereotype for the
annotated class, indicating its role. The dispatcher will scan such annotated classes
for mapped methods, detecting `@RequestMapping` annotations (see the next section).

Annotated controller beans may be defined explicitly, using a standard Spring bean
definition in the dispatcher's context. However, the `@Controller` stereotype also
allows for autodetection, aligned with Spring 2.5's general support for detecting
component classes in the classpath and auto-registering bean definitions for them.

To enable autodetection of such annotated controllers, you have to add component
scanning to your configuration. This is easily achieved by using the __spring-context__
schema as shown in the following XML snippet:

[source,xml,indent=0]
[subs="verbatim,quotes"]
----
	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:p="http://www.springframework.org/schema/p"
		xmlns:context="http://www.springframework.org/schema/context"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/context
			http://www.springframework.org/schema/context/spring-context.xsd">

		<context:component-scan base-package="org.springframework.samples.petportal.portlet"/>

		// ...

	</beans>
----



[[portlet-ann-requestmapping]]
=== Mapping requests with @RequestMapping

The `@RequestMapping` annotation is used to map portlet modes like 'VIEW'/'EDIT' onto an
entire class or a particular handler method. Typically the type-level annotation maps a
specific mode (or mode plus parameter condition) onto a form controller, with additional
method-level annotations 'narrowing' the primary mapping for specific portlet request
parameters.

[TIP]
===

`@RequestMapping` at the type level may be used for plain implementations of the
`Controller` interface as well. In this case, the request processing code would follow
the traditional `handle(Action|Render)Request` signature, while the controller's mapping
would be expressed through an `@RequestMapping` annotation. This works for pre-built
`Controller` base classes, such as `SimpleFormController`, too.

In the following discussion, we'll focus on controllers that are based on annotated
handler methods.
===

The following is an example of a form controller from the PetPortal sample application
using this annotation:

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	@Controller
	@RequestMapping("EDIT")
	@SessionAttributes("site")
	public class PetSitesEditController {

		private Properties petSites;

		public void setPetSites(Properties petSites) {
			this.petSites = petSites;
		}

		@ModelAttribute("petSites")
		public Properties getPetSites() {
			return this.petSites;
		}

		@RequestMapping // default (action=list)
		public String showPetSites() {
			return "petSitesEdit";
		}

		@RequestMapping(params = "action=add") // render phase
		public String showSiteForm(Model model) {
			// Used for the initial form as well as for redisplaying with errors.
			if (!model.containsAttribute("site")) {
				model.addAttribute("site", new PetSite());
			}

			return "petSitesAdd";
		}

		@RequestMapping(params = "action=add") // action phase
		public void populateSite(@ModelAttribute("site") PetSite petSite,
				BindingResult result, SessionStatus status, ActionResponse response) {
			new PetSiteValidator().validate(petSite, result);
			if (!result.hasErrors()) {
				this.petSites.put(petSite.getName(), petSite.getUrl());
				status.setComplete();
				response.setRenderParameter("action", "list");
			}
		}

		@RequestMapping(params = "action=delete")
		public void removeSite(@RequestParam("site") String site, ActionResponse response) {
			this.petSites.remove(site);
			response.setRenderParameter("action", "list");
		}
	}
----



[[portlet-ann-requestmapping-arguments]]
=== Supported handler method arguments
Handler methods which are annotated with `@RequestMapping` are allowed to have very
flexible signatures. They may have arguments of the following types, in arbitrary order
(except for validation results, which need to follow right after the corresponding
command object, if desired):

* Request and/or response objects (Portlet API). You may choose any specific
  request/response type, e.g. PortletRequest / ActionRequest / RenderRequest. An
  explicitly declared action/render argument is also used for mapping specific request
  types onto a handler method (in case of no other information given that differentiates
  between action and render requests).
* Session object (Portlet API): of type PortletSession. An argument of this type will
  enforce the presence of a corresponding session. As a consequence, such an argument
  will never be `null`.
* `org.springframework.web.context.request.WebRequest` or
  `org.springframework.web.context.request.NativeWebRequest`. Allows for generic request
  parameter access as well as request/session attribute access, without ties to the
  native Servlet/Portlet API.
* `java.util.Locale` for the current request locale (the portal locale in a Portlet
  environment).
* `java.util.TimeZone` / `java.time.ZoneId` for the current request time zone.
* `java.io.InputStream` / `java.io.Reader` for access to the request's content. This
  will be the raw InputStream/Reader as exposed by the Portlet API.
* `java.io.OutputStream` / `java.io.Writer` for generating the response's content. This
  will be the raw OutputStream/Writer as exposed by the Portlet API.
* `@RequestParam` annotated parameters for access to specific Portlet request
  parameters. Parameter values will be converted to the declared method argument type.
* `java.util.Map` / `org.springframework.ui.Model` / `org.springframework.ui.ModelMap`
  for enriching the implicit model that will be exposed to the web view.
* Command/form objects to bind parameters to: as bean properties or fields, with
  customizable type conversion, depending on `@InitBinder` methods and/or the
  HandlerAdapter configuration - see the " `webBindingInitializer`" property on
  `AnnotationMethodHandlerAdapter`. Such command objects along with their validation
  results will be exposed as model attributes, by default using the non-qualified
  command class name in property notation (e.g. "orderAddress" for type
  "mypackage.OrderAddress"). Specify a parameter-level `ModelAttribute` annotation for
  declaring a specific model attribute name.
* `org.springframework.validation.Errors` /
  `org.springframework.validation.BindingResult` validation results for a preceding
  command/form object (the immediate preceding argument).
* `org.springframework.web.bind.support.SessionStatus` status handle for marking form
  processing as complete (triggering the cleanup of session attributes that have been
  indicated by the `@SessionAttributes` annotation at the handler type level).

The following return types are supported for handler methods:

* A `ModelAndView` object, with the model implicitly enriched with command objects and
  the results of `@ModelAttribute` annotated reference data accessor methods.
* A `Model` object, with the view name implicitly determined through a
  `RequestToViewNameTranslator` and the model implicitly enriched with command objects
  and the results of `@ModelAttribute` annotated reference data accessor methods.
* A `Map` object for exposing a model, with the view name implicitly determined through
  a `RequestToViewNameTranslator` and the model implicitly enriched with command objects
  and the results of `@ModelAttribute` annotated reference data accessor methods.
* A `View` object, with the model implicitly determined through command objects and
  `@ModelAttribute` annotated reference data accessor methods. The handler method may
  also programmatically enrich the model by declaring a `Model` argument (see above).
* A `String` value which is interpreted as view name, with the model implicitly
  determined through command objects and `@ModelAttribute` annotated reference data
  accessor methods. The handler method may also programmatically enrich the model by
  declaring a `Model` argument (see above).
* `void` if the method handles the response itself (e.g. by writing the response content
  directly).
* Any other return type will be considered a single model attribute to be exposed to the
  view, using the attribute name specified through `@ModelAttribute` at the method level
  (or the default attribute name based on the return type's class name otherwise). The
  model will be implicitly enriched with command objects and the results of
  `@ModelAttribute` annotated reference data accessor methods.



[[portlet-ann-requestparam]]
=== Binding request parameters to method parameters with @RequestParam

The `@RequestParam` annotation is used to bind request parameters to a method parameter
in your controller.

The following code snippet from the PetPortal sample application shows the usage:

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	@Controller
	@RequestMapping("EDIT")
	@SessionAttributes("site")
	public class PetSitesEditController {

		// ...

		public void removeSite(@RequestParam("site") String site, ActionResponse response) {
			this.petSites.remove(site);
			response.setRenderParameter("action", "list");
		}

		// ...

	}
----

Parameters using this annotation are required by default, but you can specify that a
parameter is optional by setting `@RequestParam`'s `required` attribute to `false`
(e.g., `@RequestParam(value="id", required=false)`).



[[portlet-ann-modelattrib]]
=== Providing a link to data from the model with @ModelAttribute

`@ModelAttribute` has two usage scenarios in controllers. When placed on a method
parameter, `@ModelAttribute` is used to map a model attribute to the specific, annotated
method parameter (see the `populateSite()` method below). This is how the controller
gets a reference to the object holding the data entered in the form. In addition, the
parameter can be declared as the specific type of the form backing object rather than as
a generic `java.lang.Object`, thus increasing type safety.

`@ModelAttribute` is also used at the method level to provide __reference data__ for the
model (see the `getPetSites()` method below). For this usage the method signature can
contain the same types as documented above for the `@RequestMapping` annotation.

[NOTE]
====
`@ModelAttribute` annotated methods will be executed __before__ the chosen
`@RequestMapping` annotated handler method. They effectively pre-populate the implicit
model with specific attributes, often loaded from a database. Such an attribute can then
already be accessed through `@ModelAttribute` annotated handler method parameters in the
chosen handler method, potentially with binding and validation applied to it.
====

The following code snippet shows these two usages of this annotation:

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	@Controller
	@RequestMapping("EDIT")
	@SessionAttributes("site")
	public class PetSitesEditController {

		// ...

		@ModelAttribute("petSites")
		public Properties getPetSites() {
			return this.petSites;
		}

		@RequestMapping(params = "action=add") // action phase
		public void populateSite( @ModelAttribute("site") PetSite petSite, BindingResult result, SessionStatus status, ActionResponse response) {
			new PetSiteValidator().validate(petSite, result);
			if (!result.hasErrors()) {
				this.petSites.put(petSite.getName(), petSite.getUrl());
				status.setComplete();
				response.setRenderParameter("action", "list");
			}
		}
	}
----



[[portlet-ann-sessionattrib]]
=== Specifying attributes to store in a Session with @SessionAttributes

The type-level `@SessionAttributes` annotation declares session attributes used by a
specific handler. This will typically list the names of model attributes or types of
model attributes which should be transparently stored in the session or some
conversational storage, serving as form-backing beans between subsequent requests.

The following code snippet shows the usage of this annotation:

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	@Controller
	@RequestMapping("EDIT")
	@SessionAttributes("site")
	public class PetSitesEditController {
		// ...
	}
----



[[portlet-ann-webdatabinder]]
=== Customizing WebDataBinder initialization

To customize request parameter binding with PropertyEditors, etc. via Spring's
`WebDataBinder`, you can either use `@InitBinder`-annotated methods within your
controller or externalize your configuration by providing a custom
`WebBindingInitializer`.


[[portlet-ann-initbinder]]
==== Customizing data binding with @InitBinder

Annotating controller methods with `@InitBinder` allows you to configure web data
binding directly within your controller class. `@InitBinder` identifies methods which
initialize the `WebDataBinder` which will be used for populating command and form object
arguments of annotated handler methods.

Such init-binder methods support all arguments that `@RequestMapping` supports, except
for command/form objects and corresponding validation result objects. Init-binder
methods must not have a return value. Thus, they are usually declared as `void`. Typical
arguments include `WebDataBinder` in combination with `WebRequest` or
`java.util.Locale`, allowing code to register context-specific editors.

The following example demonstrates the use of `@InitBinder` for configuring a
`CustomDateEditor` for all `java.util.Date` form properties.

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	@Controller
	public class MyFormController {

		@InitBinder
		public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			dateFormat.setLenient(false);
			binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
		}

		// ...

	}
----


[[portlet-ann-webbindinginitializer]]
==== Configuring a custom WebBindingInitializer

To externalize data binding initialization, you can provide a custom implementation of
the `WebBindingInitializer` interface, which you then enable by supplying a custom bean
configuration for an `AnnotationMethodHandlerAdapter`, thus overriding the default
configuration.




[[portlet-deployment]]
== Portlet application deployment
The process of deploying a Spring Portlet MVC application is no different than deploying
any JSR-168 Portlet application. However, this area is confusing enough in general that
it is worth talking about here briefly.

Generally, the portal/portlet container runs in one webapp in your servlet container and
your portlets run in another webapp in your servlet container. In order for the portlet
container webapp to make calls into your portlet webapp it must make cross-context calls
to a well-known servlet that provides access to the portlet services defined in your
`portlet.xml` file.

The JSR-168 specification does not specify exactly how this should happen, so each
portlet container has its own mechanism for this, which usually involves some kind of
"deployment process" that makes changes to the portlet webapp itself and then registers
the portlets within the portlet container.

At a minimum, the `web.xml` file in your portlet webapp is modified to inject the
well-known servlet that the portlet container will call. In some cases a single servlet
will service all portlets in the webapp, in other cases there will be an instance of the
servlet for each portlet.

Some portlet containers will also inject libraries and/or configuration files into the
webapp as well. The portlet container must also make its implementation of the Portlet
JSP Tag Library available to your webapp.

The bottom line is that it is important to understand the deployment needs of your
target portal and make sure they are met (usually by following the automated deployment
process it provides). Be sure to carefully review the documentation from your portal for
this process.

Once you have deployed your portlet, review the resulting `web.xml` file for sanity.
Some older portals have been known to corrupt the definition of the
`ViewRendererServlet`, thus breaking the rendering of your portlets.