Apache Pluto による簡易ポータル開発(ポートレット開発編)

前回 の続き。

Spring の Portlet MVC Framework を使って、ユーザ検索を行う簡単なポートレットを開発してみる。

ポータル側の各種設定

依存性の追加

pom.xmlPortlet MVC Framework 用の依存性を追加する。

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc-portlet</artifactId>
            <version>2.5.6.SEC01</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
日本語を扱うための設定

これまではすべて英語ページだったので問題なかったが、これからは日本語を使ったポートレットも作っていくので、そのための設定を行っておく。

今回はすべてUTF-8で統一するため、web.xml の plutoPortlDriver servlet の設定に以下のようにパラメータを追加する。

    <servlet>
        <servlet-name>plutoPortalDriver</servlet-name>
        <display-name>Pluto Portal Driver</display-name>
        <description>Pluto Portal Driver Controller</description>
        <servlet-class>org.apache.pluto.driver.PortalDriverServlet</servlet-class>
        <!-- 以下を追加 -->
        <init-param>
          <param-name>charset</param-name>
          <param-value>UTF-8</param-value>
        </init-param>
    </servlet>
ポートレット設定の追加

src/main/webapp/WEB-INF/portlet.xml に、追加するポートレットの設定を追加する。Spring の Portlet MVC Framework を使うので portlet-class は DispatcherPortlet 固定。

  <portlet>
    <description>User Administration</description>
    <portlet-name>UserAdmin</portlet-name>
    <display-name>User Administration Portlet</display-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>ユーザー管理</title>
    </portlet-info>
  </portlet>
ポートレット起動用サーブレット?の設定

web.xml に、追加するポートレットポートレット名 UserAdmin)の起動用サーブレットを追加する。この辺は portlet.xml の設定から勝手にやってほしいんだけどやり方が不明なのでTODO。

  <servlet>
    <servlet-name>UserAdmin</servlet-name>
    <servlet-class>org.apache.pluto.container.driver.PortletServlet</servlet-class>
    <init-param>
      <param-name>portlet-name</param-name>
      <param-value>UserAdmin</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

(中略)

  <servlet-mapping>
    <servlet-name>UserAdmin</servlet-name>
    <url-pattern>/PlutoInvoker/UserAdmin</url-pattern>
  </servlet-mapping>
Springのビュー処理用サーブレットの設定

webt.xml に、Spring が使用するビューの設定を追加する。

  <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>

ポートレットの作成

ポートレット用のSpring Bean設定ファイルの追加

先ほど portlet.xml に設定した org.springframework.web.portlet.DispatcherPortle クラスは、デフォルトで WEB-INF/ポートレット名-portlet.xml というBean設定ファイルを読んで使用するので、src/main/webapp/WEB-INF/UserAdmin-portlet.xml というファイルを作成し、以下のように Spring MVC Framework の設定を記述する。

<?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-2.5.xsd
       ">

  <bean id="userDao" class="com.example.pluto.UserDaoImpl">
    <property name="sqlMapClient" ref="sqlMapClient" />
  </bean>

  <bean id="userAdminService" class="com.example.pluto.UserAdminServiceImpl">
    <property name="userDao" ref="userDao" />
  </bean>

  <bean id="userAdminPortletController"
    class="com.example.pluto.UserAdminPortletController">
    <property name="formView" value="userAdmin/view" />
    <property name="successView" value="userAdmin/view" />
    <property name="commandClass" value="com.example.pluto.UserAdminCommand" />
    <property name="commandName" value="userAdmin" />
    <property name="userAdminService" ref="userAdminService" />
    <property name="cacheSeconds" value="0" />
  </bean>

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

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

</beans>

共通の設定ファイル src/main/resources/applicationContext.xml に書いた定義も参照できる("sqlMapClient" 等)ので、ここではポートレット固有の設定のみを行う。

ポートレット処理を行うコントローラの追加

上記のBean定義に記述した通り、UserAdminPortletController クラスを src/main/java/com/example/pluto/UserAdminPortletController.java に以下の通り作成する。

package com.example.pluto;

import java.util.List;

import org.springframework.validation.BindException;

// 通常の Spring MVC とはパッケージが異なる
import org.springframework.web.portlet.ModelAndView;

// 通常の Spring MVC とはパッケージが異なる
import org.springframework.web.portlet.mvc.SimpleFormController;

public class UserAdminPortletController extends SimpleFormController {

    // ユーザ管理サービス
    private UserAdminService userAdminService;

    public void setUserAdminService(UserAdminService userAdminService) {
        this.userAdminService = userAdminService;
    }

    // Action時の処理
    @Override
    protected void onSubmitAction(Object commandObj, BindException errors) {
        UserAdminCommand command = (UserAdminCommand) commandObj;
        // リクエストから渡された "name" パラメータを取得
        String name = command.getName();
        List<User> users = userAdminService.findUsers(name);
        command.setUsers(users);
    }

    // Render時の処理
    @Override
    protected ModelAndView onSubmitRender(Object commandObj, BindException errors)
            throws Exception {
        UserAdminCommand command = (UserAdminCommand) commandObj;
        ModelAndView mav = new ModelAndView(getSuccessView(), errors.getModel());
        // onSubmitAction() で取得した情報をJSPで ${users} のように参照できるようにする
        mav.addObject("users", command.getUsers());
        return mav;
    }
}

一応、StrutsでいうところのForm的なコマンドクラスは以下のような感じ。

ackage com.example.pluto;

import java.io.Serializable;
import java.util.List;

public class UserAdminCommand implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private String name;

    private List<User> users;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

UserAdminService などは普通にデータベースからユーザ情報を検索したりするだけなので省略。

JSPの追加

src/main/webapp/WEB-INF/fragments/userAdmin/view.jsp に以下のようなJSPを追加する。

<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<portlet:defineObjects />
<portlet:actionURL var="formActionUrl"/>

<form:form commandName="userAdmin" action="${formActionUrl}" method="get">
  <p>ユーザ名(前方一致): <form:input path="name" /> <input type="submit" value="検索" /></p>
</form:form>

<c:if test="${users != null}">
<hr />

<table border="1">
<tr>
  <th>ID</th>
  <th>ユーザ名</th>
  <th>有効フラグ</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
  <td><c:out value="${user.id}" /></td>
  <td><c:out value="${user.name}" /></td>
  <td><c:out value="${user.enabled}" /></td>
</tr>
</c:forEach>
</table>

</c:if>

実行確認

新しいポートレットをDBに追加

portal.sqlite3 に以下のように新しいポートレットを含むページを追加する。

-- ポートレット設定を追加
insert into portlets values (3, 'UserAdmin', '/portal-example');
-- ページを追加
insert into pages values (3, 'User Admin Page', '/WEB-INF/themes/pluto-default-theme.jsp');
-- 追加したページとポートレットを関連付け
insert into pages_portlets values (3, 1, 3);
-- 追加したページを ROLE_ADMIN ロールと関連付け
insert into roles_pages values (2, 3, 3);
確認

http://localhost:8080/portal-example/ にアクセスし、admin ユーザでログインする。

  • "User Admin Page" ページが表示される
  • "User Admin Page" ページにアクセスすると、作成したポートレットが表示される
  • 「ユーザー名」欄に情報を入力してsubmitすると結果が表示される

ことを確認する。