PortletMVC4Spring
NOTE ON BRANCHES
- The PortletMVC4Spring master branch was intended to be reserved for compatibility with Spring Framework 6.x, but
since Pivotal made the move from the
javax.
to thejakarta.
package namespace, the PortletMVC4Spring master branch remains unused. See Version Scheme for more information about the 5.3,x, 5.2.x, and 5.1.x branches.
The PortletMVC4Spring project began as Spring Portlet MVC and was part of the Spring Framework. When the project was pruned from version 5.0.x of the Spring Framework under SPR-14129, it became necessary to fork and rename the project. This made it possible to improve and maintain the project for compatibility with the latest versions of the Spring Framework and the Portlet API.
Liferay, Inc. adopted Spring Portlet MVC in March of 2019 and the project was renamed to PortletMVC4Spring.
In June of 2021, Liferay also adopted the portlet-related source from the Spring Web Flow project and incorporated it into a separate "webflow" module within the PortletMVC4Spring project.
Documentation
Library Modules
Module | Description |
---|---|
com.liferay.portletmvc4spring.framework | Provides the Model/View/Controller (MVC) portlet framework. |
com.liferay.portletmvc4spring.security | Provides convenience and utility classes that help support Cross-Site Request Forgery (CSRF) protection provided by Spring Security. For more information, see Enabling CSRF Protection. |
com.liferay.portletmvc4spring.webflow | Provides the portlet framework that is built on top of Spring Web Flow. |
Requirements
PortletMVC4Spring requires JDK 8+ and has been upgraded from version 2.0 of the Portlet API to version 3.0. In addition, it has been refactored and tested for use with version 5.1.x, 5.2,x, and 5.3.x of the Spring Framework.
Supported Portals
PortletMVC4Spring is supported in the following Portlet 3.0 compliant portals:
Version Scheme
PortletMVC4Spring follows a major.minor.patch
version scheme. The major
and minor
version numbers correspond to
Spring Framework versions for which PortletMVC4Spring is compatible. For example, version 5.3.x of PortletMVC4Spring is
intended for use with Spring Framework 5.3.x, version 5.2.x of PortletMVC4Spring is intended for use with Spring
Framework 5.2.x, and so on. The patch
number indicates an incremental version containing patches for software defects.
Dependency Coordinates
Maven:
<dependencies>
<dependency>
<groupId>com.liferay.portletmvc4spring</groupId>
<artifactId>com.liferay.portletmvc4spring.framework</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>com.liferay.portletmvc4spring</groupId>
<artifactId>com.liferay.portletmvc4spring.security</artifactId>
<version>5.3.2</version>
</dependency>
<!-- Only required for portlets that use Spring Web Flow -->
<!--
<dependency>
<groupId>com.liferay.portletmvc4spring</groupId>
<artifactId>com.liferay.portletmvc4spring.webflow</artifactId>
<version>5.3.2</version>
</dependency>
-->
<dependencies>
Gradle:
dependencies {
compile group: 'com.liferay.portletmvc4spring', name: 'com.liferay.portletmvc4spring.framework', version: '5.3.2'
compile group: 'com.liferay.portletmvc4spring', name: 'com.liferay.portletmvc4spring.security', version: '5.3.2'
// Only required for portlets that use Spring Web Flow
// compile group: 'com.liferay.portletmvc4spring', name: 'com.liferay.portletmvc4spring.webflow', version: '5.3.2'
}
Archetypes
# JSP Form
mvn archetype:generate \
-DarchetypeGroupId=com.liferay.portletmvc4spring.archetype \
-DarchetypeArtifactId=com.liferay.portletmvc4spring.archetype.form.jsp.portlet \
-DarchetypeVersion=5.3.2 \
-DgroupId=com.mycompany \
-DartifactId=com.mycompany.my.form.jsp.portlet
# Thymeleaf Form
mvn archetype:generate \
-DarchetypeGroupId=com.liferay.portletmvc4spring.archetype \
-DarchetypeArtifactId=com.liferay.portletmvc4spring.archetype.form.thymeleaf.portlet \
-DarchetypeVersion=5.3.2 \
-DgroupId=com.mycompany \
-DartifactId=com.mycompany.my.form.thymeleaf.portlet
Demos
There are two demos available that have been tested in both Liferay Portal and Apache Pluto:
The demos exercise many of the features of PortletMVC4Spring that developers typically need for form-based portlet applications. The first two demos are identical except that one uses JSPX views and the other uses Thymeleaf views.
Migration
If you are migrating a portlet project from Spring Portlet MVC to PortletMVC4Spring, then follow these steps:
-
Upgrade your pom.xml or build.gradle descriptor to version 5.1.x of the Spring Framework.
-
Replace the
spring-webmvc-portlet
dependency in your pom.xml or build.gradle descriptor with thecom.liferay.portletmvc4spring.framework
dependency. For more information about adding dependencies, see Dependency Coordinates. -
Replace
org.springframework.web.portlet.DispatcherPortlet
withcom.liferay.portletmvc4spring.DispatcherPortlet
in your WEB-INF/portlet.xml descriptor. -
The Spring Portlet MVC AnnotationMethodHandlerAdapter class was replaced with the new PortletMVC4Spring PortletRequestMappingHandlerAdapter class in order to utilize the modern-day HandlerMethod infrastructure that Spring Web MVC is based on.
If you specified
AnnotationMethodHandlerAdapter
as a<bean>
in a Spring configuration descriptor, then you will need to replace theorg.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter
fully-qualified class name (FQCN) withcom.liferay.portletmvc4spring.mvc.method.annotation.PortletRequestMappingHandlerAdapter
. In addition, the following properties have changed:
-
customModelAndViewResolver (no longer available)
-
customArgumentResolver (no longer available)
-
customArgumentResolvers (specify a list of HandlerMethodArgumentResolver instead of a list of WebArgumentResolver)
- If using Apache Commons Fileupload, then update your Spring configuration descriptor:
- Replace the following legacy bean:
<bean id="portletMultipartResolver"
class="org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver" />
- With the new one from PortletMVC4Spring:
<bean id="portletMultipartResolver"
class="com.liferay.portletmvc4spring.multipart.CommonsPortletMultipartResolver" />
Alternatively, you can upgrade to the native Portlet 3.0 file upload support provided by PortletMVC4Spring by updating your Spring configuration descriptor:
- Replace the following legacy bean:
<bean id="portletMultipartResolver"
class="org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver" />
- With the new one from PortletMVC4Spring:
<bean id="portletMultipartResolver"
class="com.liferay.portletmvc4spring.multipart.StandardPortletMultipartResolver" />
- Finally, remove the following dependencies from your pom.xml or build.gradle descriptor:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
- Perform a global search and replace of "org.springframework.web.portlet" with "com.liferay.portletmvc4spring" within your project.
Enabling CSRF Protection
Liferay Portal provides CSRF protection out-of-the-box for the ACTION_PHASE
of the portlet lifecycle via the
p_auth
request parameter (present on all ActionURLs). If a developer uses XmlHttpRequest (XHR) to submit forms with
the RESOURCE_PHASE
, then the developer is responsible for providing CSRF protection.
The PortletMVC4Spring security module has the ability to enable CSRF protection for both the ACTION_PHASE
and
RESOURCE_PHASE
in any supported portal. In the case of Liferay Portal, the PortletMVC4Spring CSRF protection is
redundant with Liferay Portal's out-of-the-box CSRF protection for the ACTION_PHASE
.
In order to enable CSRF protection, follow these steps:
-
Add the
com.liferay.portletmvc4spring.security
library as a dependency to your portlet project. For more information, see Dependency Coordinates. -
Add the following to your WEB-INF/spring-context/portlet-application-context.xml descriptor:
<bean id="springSecurityPortletConfigurer"
class="com.liferay.portletmvc4spring.security.SpringSecurityPortletConfigurer" />
<bean id="delegatingFilterProxy" class="org.springframework.web.filter.DelegatingFilterProxy">
<property name="targetBeanName" value="springSecurityFilterChain" />
</bean>
- Add the following to your WEB-INF/portlet.xml descriptor:
<filter>
<filter-name>SpringSecurityPortletFilter</filter-name>
<filter-class>com.liferay.portletmvc4spring.security.SpringSecurityPortletFilter</filter-class>
<lifecycle>ACTION_PHASE</lifecycle>
<lifecycle>RENDER_PHASE</lifecycle>
<lifecycle>RESOURCE_PHASE</lifecycle>
<filter>
<filter-mapping>
<filter-name>SpringSecurityPortletFilter</filter-name>
<!-- NOTE: Specify a portlet-name element for each and every portlet -->
<!-- that you want protected! -->
<portlet-name>portlet1</portlet-name>
</filter-mapping>
- Add the following to your WEB-INF/web.xml descriptor:
<filter>
<filter-name>delegatingFilterProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>delegatingFilterProxy</filter-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
Issues
Defects and feature requests can be posted in the PortletMVC4Spring Issue Tracker.
License
PortletMVC4Spring is released under the Apache License, Version 2.0.
Building From Source
Using Maven 3.x:
mvn clean install
Community Participation
For code contributions, see CONTRIBUTING.
Post questions in the Liferay Development Forum.