PortletMVC4Spring Configuration Files
A PortletMVC4Spring application has these descriptors, Spring contexts, and properties files in its WEB-INF
folder:
web.xml
→ Web application descriptorportlet.xml
→ Portlet application descriptorliferay-portlet.xml
→ Liferay-specific portlet descriptorliferay-display.xml
→ Liferay-specific display descriptorspring-context/portlet-application-context.xml
→ Portlet application contextspring-context/portlet/[portlet]-context.xml
→ Portlet contextliferay-plugin-package.properties
→ Packaging descriptor
Examples of each file are provided and portlet-specific content is highlighted.
web.xml
The servlet container processes the web.xml
. This file specifies the servlet that render’s the portlet and the portlet application’s context, servlet, filters, listeners, and more. Here’s an example web.xml
:
<?xml version="1.0"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context/portlet-application-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>com.liferay.portletmvc4spring.ViewRendererServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
The <context-param/>
element gives the path to the portlet application context (discussed later):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context/portlet-application-context.xml</param-value>
</context-param>
The <servlet/>
and <servlet-mapping/>
elements set the servlet and the internal location for its views.
<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>com.liferay.portletmvc4spring.ViewRendererServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
The ViewRendererServlet
. converts portlet requests into servlet requests and enables the view to be rendered using the Spring Web MVC infrastructure and the infrastructure’s renderers for JSP, Thymeleaf, Velocity, and more.
The filter and filter mappings are set to forward and include servlet views as necessary.
<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>
A listener is configured for processing the application’s contexts.
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Liferay’s project archetypes generate all this boilerplate code.
portlet.xml
The portlet.xml
file describes the portlet application to the portlet container. Here’s an example:
<?xml version="1.0"?>
<portlet-app xmlns="http://xmlns.jcp.org/xml/ns/portlet" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet http://xmlns.jcp.org/xml/ns/portlet/portlet-app_3_0.xsd" version="3.0">
<portlet>
<portlet-name>portlet1</portlet-name>
<display-name>com.mycompany.my.form.jsp.portlet</display-name>
<portlet-class>com.liferay.portletmvc4spring.DispatcherPortlet</portlet-class>
<init-param>
<name>contextConfigLocation</name>
<value>/WEB-INF/spring-context/portlet/portlet1-context.xml</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<resource-bundle>content.portlet1</resource-bundle>
<portlet-info>
<title>com.mycompany.my.form.jsp.portlet</title>
<short-title>com.mycompany.my.form.jsp.portlet</short-title>
<keywords>com.mycompany.my.form.jsp.portlet</keywords>
</portlet-info>
<security-role-ref>
<role-name>administrator</role-name>
</security-role-ref>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
<security-role-ref>
<role-name>power-user</role-name>
</security-role-ref>
<security-role-ref>
<role-name>user</role-name>
</security-role-ref>
</portlet>
<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>
<portlet-name>portlet1</portlet-name>
</filter-mapping>
</portlet-app>
This application has one portlet named portlet1
.
<portlet-name>portlet1</portlet-name>
<display-name>com.mycompany.my.form.jsp.portlet</display-name>
<portlet-class>com.liferay.portletmvc4spring.DispatcherPortlet</portlet-class>
The <portlet-name/>
is internal and the <display-name/>
is shown to users. <portlet-class/>
specifies the portlet’s Java class.
Important: All PortletMVC4Spring portlets must specify <portlet-class>com.liferay.portletmvc4spring.DispatcherPortlet</portlet-class>
.
The <supports/>
element must declare the mime type that the portlet templates use.
The <resource-bundle/>
sets the path to the portlet’s localized Java message properties. For example, the element refers to properties at content/portlet1.properties
:
<resource-bundle>content.portlet1</resource-bundle>
The <portlet-info/>
element lists the portlet’s titles and reserved keyword.
The <security-role-ref/>
elements declare default user roles the portlet accounts for.
Lastly, the <filter/>
named SpringSecurityPortletFilter
prevents Cross-Site Request Forgery (CSRF).
<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>
<portlet-name>portlet1</portlet-name>
</filter-mapping>
The portlet XSD
defines the portlet.xml
. The Liferay-specific portlet descriptor is next.
liferay-portlet.xml
The liferay-portlet.xml
file applies Liferay-specific settings that provide more developer features. Here’s an example:
<?xml version="1.0"?>
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 7.4.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_7_4_0.dtd">
<liferay-portlet-app>
<portlet>
<portlet-name>portlet1</portlet-name>
<icon>/resources/images/icon.png</icon>
<requires-namespaced-parameters>false</requires-namespaced-parameters>
</portlet>
<role-mapper>
<role-name>administrator</role-name>
<role-link>Administrator</role-link>
</role-mapper>
<role-mapper>
<role-name>guest</role-name>
<role-link>Guest</role-link>
</role-mapper>
<role-mapper>
<role-name>power-user</role-name>
<role-link>Power User</role-link>
</role-mapper>
<role-mapper>
<role-name>user</role-name>
<role-link>User</role-link>
</role-mapper>
</liferay-portlet-app>
This <portlet/>
element associates an icon with the portlet and indicates that name-spaced parameters aren’t required.
The <role-mapper/>
elements associate the portlet with default Liferay DXP user roles.
The liferay-portlet-app-[version].dtd
file defines the liferay-portlet.xml
file.
liferay-display.xml
The liferay-display.xml
applies display characteristics to the portlet. For example, this descriptor associates the portlet with a Widget category in Liferay DXP’s Add Widget menu.
<?xml version="1.0"?>
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 7.4.0//EN" "http://www.liferay.com/dtd/liferay-display_7_4_0.dtd">
<display>
<category name="category.sample">
<portlet id="portlet1" />
</category>
</display>
See liferay-display-[version].dtd
file for details.
It’s time to look at the application contexts.
Portlet Application Context
This context applies to all of the application’s portlets. This is where you specify view resolvers, resource bundles, security beans, proxies, and more. Here’s an example:
<?xml version="1.0"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jspx" />
<property name="viewClass" value="com.liferay.portletmvc4spring.PortletJstlView" />
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>content.portlet1</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="springSecurityPortletConfigurer" class="com.liferay.portletmvc4spring.security.SpringSecurityPortletConfigurer" />
<bean id="delegatingFilterProxy" class="org.springframework.web.filter.DelegatingFilterProxy">
<property name="targetBeanName" value="springSecurityFilterChain" />
</bean>
</beans>
The view resolver bean above handles JSPX view templates. To resolve Thymeleaf view templates, for example, you could specify these beans:
<bean class="org.thymeleaf.templateresolver.ServletContextTemplateResolver" id="templateResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
</bean>
<bean class="org.thymeleaf.spring5.SpringTemplateEngine" id="templateEngine">
<property name="templateResolver" ref="templateResolver"></property>
<property name="enableSpringELCompiler" value="true" />
</bean>
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver" id="viewResolver">
<property name="templateEngine" ref="templateEngine"/>
<property name="order" value="1"/>
</bean>
The context’s springSecurityPortletConfigurer
bean facilitates using Spring Security:
<bean id="springSecurityPortletConfigurer"
class="com.liferay.portletmvc4spring.security.SpringSecurityPortletConfigurer" />
You can also designate contexts for each portlet in the application.
Portlet Contexts
Beans specific to a portlet, go in the portlet’s context. Since annotations are the easiest way to develop PortletMVC4Spring portlets, you should specify MVC annotation scanning in the portlet context:
<?xml version="1.0"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="portlet1**"/>
<mvc:annotation-driven/>
</beans>
The portlet context naming convention is [portlet-name]-context.xml
. To associate your portlet with its own context, edit your application’s portlet.xml
file and add an <init-param/>
element that maps the <portlet/>
element to the portlet’s context:
<init-param>
<name>contextConfigLocation</name>
<value>/WEB-INF/spring-context/portlet/portlet1-context.xml</value>
</init-param>
What’s left is to describe your application package.
liferay-plugin-package.properties
This file specifies the application’s name, version, Java package imports/exports, and OSGi metadata. Here’s an example package properties file:
author=N/A
change-log=
licenses=N/A
liferay-versions=7.2.0+
long-description=
module-group-id=com.mycompany
module-incremental-version=1
name=com.mycompany.my.form.jsp.portlet
page-url=
short-description=my portlet short description
tags=myTag
Bundle-Version: 1.0.0
Import-Package: com.liferay.portal.webserver,com.liferay.portal.kernel.servlet.filters.invoker
It uses this OSGi metadata header to import required Java packages:
Import-Package: com.liferay.portal.webserver,\
com.liferay.portal.kernel.servlet.filters.invoker
On deploying the portlet application WAR file, the WAB Generator adds the specified OSGi metadata to the resulting web application bundle (WAB) that’s deployed to Liferay’s runtime framework.
The liferay-plugin-package-[version].dtd
file describes the liferay-plugin-package.properties
file.