Configuring a Spring MVC Portlet

This isn’t a comprehensive guide to configuring a Spring MVC portlet. It covers the high points, assuming you already have familiarity with Spring MVC. If you don’t, you should consider using Liferay’s MVC framework.

What does a Liferay Spring MVC portlet look like? Almost identical to any other Spring MVC portlet.

Portlet Configuration

In the portlet.xml file’s portlet-class element you must declare Spring’s DispatcherPortlet:

<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>

The Spring front controller needs to know where the application context file is, so specify it as an initialization parameter in the portlet.xml (update the path as needed):

<init-param>
    <name>contextConfigLocation</name>
    <value>/WEB-INF/spring/portlet-context.xml</value>
</init-param>

Provide an application context file (portlet-context.xml in the example above), specified as you normally would for your Spring MVC portlet. Next configure your web application.

Web Application Configuration

If you’re letting Liferay generate the WAB for you (this is the recommended approach), the elements are added automatically during auto-deployment.

If you’re configuring an OSGi Web Application Bundle (WAB) yourself, the web.xml file in your Spring MVC project must be fully ready for deployment. In addition to your Spring MVC configuration, your web.xml must include these elements:

The elements look like this:

<listener>
    <listener-class>com.liferay.portal.kernel.servlet.PluginContextListener</listener-class>
</listener>
<servlet>
    <servlet-name>Portlet Servlet</servlet-name>
    <servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Portlet Servlet</servlet-name>
    <url-pattern>/portlet-servlet/*</url-pattern>
</servlet-mapping>

Your application must be able to convert javax.portlet.PortletRequests to javax.servlet.ServletRequests and back again. Add this to the web.xml:

<servlet>
    <servlet-name>ViewRendererServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.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>

That’s all the configuration that’s necessary for web.xml. Now you’re ready to configure the views.

Views

To configure the Spring view resolver, add a bean to your application context file (portlet-context.xml in the previous example):

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

Now the front controller, org.springframework.web.portlet.DispatcherPortlet, can get a request from the view layer, so now it’s time to configure controller classes to handle the requests.

Controllers

With Spring MVC, your controller is conveniently separated into classes that handle the portlet modes (View, Edit, Help).

You’ll use Spring’s annotations to configure the controller and tell DispatcherPortlet which mode the controller supports.

View Mode Controller

A simple controller class supporting View mode might look like this:

@Controller("myAppController")
@RequestMapping("VIEW")
public class MyAppController {

    @RenderMapping
    public String processRenderRequest(RenderRequest request,
            RenderResponse response) {

        return "defaultView";
    }
}

The return defaultView statement should be understood in terms of the view resolver bean in the application context file, which gives the String defaultView a prefix of WEB-INF/views/, and a suffix of .jsp. That maps to the path WEB-INF/views/defaultView.jsp, where you would place your default view for the application.

With Spring MVC, you can only support one portlet phase in each controller.

Edit Mode Controller

An edit mode controller might contain render methods and action methods.

@Controller("myAppEditController")
@RequestMapping("EDIT")
public class MyAppEditController {

    @RenderMapping
    public String processRenderRequest(RenderRequest request,
            RenderResponse response) {

        return "thisView";
    }

    @ActionMapping(params="action=doSomething")
    public void doSomething(Actionrequest request, ActionResponse response){
    
        // Do something here

    }
}

Make sure to define any controller classes in your application context file by adding a bean element for each one:

<bean class="com.liferay.docs.springmvc.portlet.MyAppController" />
<bean class="com.liferay.docs.springmvc.portlet.MyAppEditController" />

Develop your controllers and your views as you normally would in a Spring MVC portlet. You must also provide some necessary descriptors for Liferay.

Liferay Descriptors

Liferay portlet plugins that are packaged as WAR files should include some Liferay specific descriptors.

The descriptor liferay-display.xml controls the category in which your portlet appears in Liferay DXP’s Add menu. Find the complete DTD here.

Here’s a simple example that specifies a new category for the application in Liferay’s menu for adding applications:

<display>
    <category name="New Category">
        <portlet id="example-portlet" />
    </category>
</display>

The descriptor liferay-portlet.xml specifies additional information about the portlet (like the location of CSS and JavaScript files or the portlet’s icon. A complete list of the attributes you can set can be found here

<liferay-portlet-app>
    <portlet>
        <portlet-name>example-portlet</portlet-name>
        <instanceable>true</instanceable>
        <render-weight>0</render-weight>
        <ajaxable>true</ajaxable>
        <header-portlet-css>/css/main.css</header-portlet-css>
        <footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
        <footer-portlet-javascript>/js/jquery.foundation.orbit.js</footer-portlet-javascript>
    </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>

You’ll also notice the role-mapper elements included above. They define the Liferay roles used in the portlet.

The liferay-plugin-package.properties file describes the Liferay plugin, declares its resources, and specifies its security related parameters. The DTD is here.

name=example-portlet
module-group-id=liferay
module-incremental-version=1
tags=
short-description=
change-log=
page-url=http://www.liferay.com
author=Liferay, Inc.
licenses=LGPL
version=1

In the liferay-plugin-package.properties file, you can also add OSGi metadata which the Liferay WAB Generator adds to the MANIFEST.MF file when you deploy your WAR file.

All of Liferay’s DTDs are here.

Calling Services from Spring MVC

To call OSGi-based Service Builder services from your Spring MVC portlet, you need a mechanism that gives you access to the OSGi service registry.

Since you’re in the context of a Spring MVC portlet, you can’t look up a reference to the services (including Service Builder services) published to the OSGi runtime using Declarative Services. You have to use Service Trackers. There’s some boilerplate code involved, but the ability to look up services in the OSGi runtime is worth it.

Next consider how to package and deploy your Spring MVC portlet.

« Spring MVCDeploying a Spring MVC Portlet »
この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています