블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

포틀릿을 생성하고 세부사항에 대하여 알아보고, 포틀릿의 두가지 Phase를 이해하자. 이를 위해 Maven 기반으로 포틀릿을 생성하고 Java와 JSP를 생성/수정해 보도록 한다. 

완성된 포틀릿의 edit 모습

 


포틀릿 생성

  - 이클립스 IDE를 통한 생성

  - CLI 명령으로 통한 생성

// CLI 생성

// 이름의 뒤에 자동으로 "-portlet"이 붙는다 

$ cd ~/development/liferay_portal/plugins-sdk-6.2/portlets

$ create.sh mobiconsoft-greeting "hi youngsik"

Buildfile: /Users/xxx/development/liferay_portal/plugins-sdk-6.2/portlets/build.xml

.. 중략 ..

BUILD SUCCESSFUL

Total time: 1 second


// 배포

$ ant deploy 

Buildfile: /Users/xxx/development/liferay_portal/plugins-sdk-6.2/portlets/build.xml

deploy:

    .. 중략 ..

     [copy] Copying 1 file to /Users/xxx/development/liferay_portal/portal-6.2-ce-ga2/deploy

BUILD SUCCESSFUL

Total time: 9 seconds


* 만일 tomcat ROOT를 변경하였다면 deploy/*.war는 기본 폴더인 {TOMCAT_HOME}/webapps/ 밑으로 들어간다. 

tomcat을 수행하기전에 deploy/*.war 파일을 변경된 폴더 밑으로 copy한 후 시작한다. (변경된 폴더로 deploy하는 설정을 못 찾겠음)



Portlet 구조이해

  - 톰켓에 배포된 디렉토리 구조

> 자바 소스, 웹 리소스, 환경 설정 3가지로 구성되어있다.

  톰켓의 단일 Context로 운영된다. 즉, J2EE Context 폴더 구조임 


> xml 환경파일들

 portlet.xml : JSR-286 Portlet 스펙에 대한 환경파일

 liferay-display.xml : 화면구성 위저드에서 카테고리 지정 

 liferay-plugin-package.properties : hot deploy 설정

 liferay-portlet.xml : liferay portal server와 특화된 portlet 설정들

 

> 리소스들

 html : 클라이언트에 표현되는 것으로 <html>, <head> 태그는 없어야 함

 css, js : 다른 css와 충돌하지 않도록 namespace를 준다 


  - portlet.xml

    + MVCPortlet : 포틀릿 전체 기능이 내장된 놈. 우리가 만드는 포틀릿은 실제 요것을 상속받아서 구현된다. 

    + portlet-info : 카테고리되었을 때 이름 지정 

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0">

<portlet>

<portlet-name>mobiconsoft-greeting</portlet-name>

<display-name>hi youngsik</display-name>

<portlet-class>com.liferay.util.bridges.mvc.MVCPortlet</portlet-class>

<init-param>

<name>view-template</name>

<value>/view.jsp</value>

</init-param>

<expiration-cache>0</expiration-cache>

<supports>

<mime-type>text/html</mime-type>

</supports>

<portlet-info>

<title>hi youngsik</title>

<short-title>hi youngsik</short-title>

<keywords>hi youngsik</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>

</portlet-app>


  - liferay-portlet.xml 

    + header-portlet-css : <header> 태그에 들어갈 css 

    + footer-portlet-javascripit : </body> 끝에 들어갈 javascript 

    + instanceable : 해당 포틀릿이 한페이지 멀티로 나오는 인스턴스들인지 true / false 설정

<?xml version="1.0"?>

<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 6.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_6_2_0.dtd">


<liferay-portlet-app>

<portlet>

<portlet-name>mobiconsoft-greeting</portlet-name>

<icon>/icon.png</icon>

<header-portlet-css>/css/main.css</header-portlet-css>

<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>

<css-class-wrapper>mobiconsoft-greeting-portlet</css-class-wrapper>

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



포틀릿을 수정해 보기 

  - liferay-portal.xml 에서 instanceable=false 추가 

<instanceable>false</instanceable>

  - view.jsp 파일 수정 

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<%@ page import="javax.portlet.PortletPreferences" %>


<portlet:defineObjects />


<%

PortletPreferences prefs = renderRequest.getPreferences();

String greeting = (String)prefs.getValue("greeting", "Hello! Welcome to our portal.");

%>


<p><%= greeting %></p>


<portlet:renderURL var="editGreetingURL">

    <portlet:param name="mvcPath" value="/edit.jsp" />

</portlet:renderURL>


<p><a href="<%= editGreetingURL %>">Edit greeting</a></p>

  - edit.jsp 파일 신규 추가

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>


<%@ page import="javax.portlet.PortletPreferences" %>


<portlet:defineObjects />


<%

PortletPreferences prefs = renderRequest.getPreferences();

String greeting = renderRequest.getParameter("greeting");

if (greeting != null) {

    prefs.setValue("greeting", greeting);

    prefs.store();

%>

    <p>Greeting saved successfully!</p>

<%

}

%>


<%

greeting = (String)prefs.getValue("greeting", "Hello! Welcome to our portal.");

%>


<portlet:renderURL var="editGreetingURL">

    <portlet:param name="mvcPath" value="/edit.jsp" />

</portlet:renderURL>


<aui:form action="<%= editGreetingURL %>" method="post">

    <aui:input label="greeting" name="greeting" type="text" value="<%=greeting %>" />

    <aui:button type="submit" />

</aui:form>


<portlet:renderURL var="viewGreetingURL">

    <portlet:param name="mvcPath" value="/view.jsp" />

</portlet:renderURL>


<p><a href="<%= viewGreetingURL %>">&larr; Back</a></p>

  - {SDK}/portlets 밑에서 수정했으면 다시 deploy를 이미 www 폴더에서 수정했다면 tomcat 다시 restart 한다.

// 수정한 view.jsp 


// 신규 추가한 edit.jsp 



  - *.jsp 에서 중요한 사항

    +  http://java.sun.com/portlet_2_0 에서 정의한 <portlet:renderURL> 태그(taglib)를 사용한다  

    +  edit.jsp에서 aui(AlloyUI == YUI3)를 이용하여 form을 만들고 있다 

    + <portlet:defineObjects/> 를 넣으면 renderRequest, portletConfig, portletPreferences 를 jsp에서 사용할 수 있다. 이것은 jsp에서만 유효하고 여러가지 오브젝트를 사용토록 해준다 

RenderRequest renderRequest: represents the request sent to the portlet to handle a render. renderRequest is only available to a JSP if the JSP was included during the render request phase.


ResourceRequest resourceRequest: represents the request sent to the portlet for rendering resources. resourceRequest is only available to a JSP if the JSP was included during the resource-serving phase.


ActionRequest actionRequest: represents the request sent to the portlet to handle an action. actionRequest is only available to a JSP if the JSP was included during the action-processing phase.


EventRequest eventRequest: represents the request sent to the portlet to handle an event. eventRequest is only available to a JSP if the JSP was included during the event-processing phase.


RenderResponse renderResponse: represents an object that assists the portlet in sending a response to the portal. renderResponse is only available to a JSP if the JSP was included during the render request phase.


ResourceResponse resourceResponse: represents an object that assists the portlet in rendering a resource. resourceResponse is only available to a JSP if the JSP was included in the resource-serving phase.


ActionResponse actionResponse: represents the portlet response to an action request. actionResponse is only available to a JSP if the JSP was included in the action-processing phase.


EventResponse eventResponse: represents the portlet response to an event request. eventResponse is only available to a JSP if the JSP was included in the event-processing phase.


PortletConfig portletConfig: represents the portlet’s configuration including, the portlet’s name, initialization parameters, resource bundle, and application context. portletConfig is always available to a portlet JSP, regardless of the request-processing phase in which it was included.


PortletSession portletSession: provides a way to identify a user across more than one request and to store transient information about a user. A portletSession is created for each user client. portletSession is always available to a portlet JSP, regardless of the request-processing phase in which it was included. portletSession is null if no session exists.


Map<String, Object> portletSessionScope: provides a Map equivalent to the PortletSession.getAtrributeMap() call or an empty Map if no session attributes exist.


PortletPreferences portletPreferences: provides access to a portlet’s preferences. portletPreferences is always available to a portlet JSP, regardless of the request-processing phase in which it was included.


Map<String, String[]> portletPreferencesValues: provides a Map equivalent to the portletPreferences.getMap() call or an empty Map if no portlet preferences exist.



Liferay IDE를 통한 개발 (주의사항)

  - 기본 {TOMCAT_HOME}/webapps/ROOT 를 사용한다. 

  - 기존 ~/liferay_portal/www 에서 다시 원위치로 설정한다.

1) {TOMCAT_HOME}/conf.xml 에서 위치 변경

<Host appBase="/Users/xxx/development/liferay_portal/portal-6.2-ce-ga2/tomcat-7.0.42/webapps" autoDeploy="true" name="localhost" unpackWARs="true">


2) {PLUGIN_SDK}/build.<username>.properties

app.server.tomcat.lib.global.dir = /Users/xxx/development/liferay_portal/portal-6.2-ce-ga2/tomcat-7.0.42/lib/ext

app.server.tomcat.deploy.dir = /Users/xxx/development/liferay_portal/portal-6.2-ce-ga2/tomcat-7.0.42/webapps

app.server.parent.dir = /Users/xxx/development/liferay_portal/portal-6.2-ce-ga2

app.server.tomcat.dir = /Users/xxx/development/liferay_portal/portal-6.2-ce-ga2/tomcat-7.0.42

app.server.type = tomcat

app.server.tomcat.portal.dir = /Users/xxx/development/liferay_portal/portal-6.2-ce-ga2/tomcat-7.0.42/webapps/ROOT

  - 또한 Maven으로 생성시 pom.xml에서 <version> 은 "1.0.0-SNAPSHOT"이 아니라 "portlet" 이라고 준다 



포틀릿의 2 Phase Execution 이해 

  - Action Phase와 Render Phase로 구성된다

  - Action Phase

    + 하나의 포틀릿에서만 유저 인터렉션이 일어날 수있다. 

    + 사용자의 prefereneces는 한번만 변경되고 재변경되지 않는다 

  - Render Phase

    + action phase가 있은 후 모든 포틀릿의 render phase를 호출한다.

1) action phase를 만들기위해서 기존에 Eclipse에서 생성한 "mobiconsoft-sample"에서 자바소스를 추가한다 

    (CLI 방식일 경우 : {SDK}/porlets/mobiconsoft-sample-portlet/WEB-INF/src 밑에 둔다)

     MVCPorlet을 상속받는다 

package com.mobiconsoft.sample;


import java.io.IOException;

import javax.portlet.ActionRequest;

import javax.portlet.ActionResponse;

import javax.portlet.PortletException;

import javax.portlet.PortletPreferences;

import com.liferay.util.bridges.mvc.MVCPortlet;


public class YoungSikGreetingPortlet extends MVCPortlet {

    @Override

    public void processAction(ActionRequest actionRequest, ActionResponse actionResponse)

        throws IOException, PortletException {

        PortletPreferences prefs = actionRequest.getPreferences();

        String greeting = actionRequest.getParameter("greeting");


        if (greeting != null) {

            prefs.setValue("greeting", greeting);

            prefs.store();

        }


        super.processAction(actionRequest, actionResponse);

    }

}


2) portlet.xml 파일의 내용에서 MVCPortlet을 바꾼다 

<portlet-class>com.mobiconsoft.sample.YoungSikGreetingPortlet</portlet-class>


3) edit.jsp 안에 action을 넣어보자 

   - renderURL : render phase에서만 호출 된다 

   - actionURL : 페이지안의 모든 포틀릿을 rendering 하기전에 action phase를 수행한다

   - resourceURL : xml, images, json, AJAX 요청등

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>


<%@ page import="com.liferay.portal.kernel.util.ParamUtil" %>

<%@ page import="com.liferay.portal.kernel.util.Validator" %>

<%@ page import="javax.portlet.PortletPreferences" %>


<portlet:defineObjects />


<%

    PortletPreferences prefs = renderRequest.getPreferences();

    String greeting = (String)prefs.getValue("greeting", "Hello! Welcome to our portal.");

%>


<portlet:actionURL var="editGreetingURL">

    <portlet:param name="mvcPath" value="/edit.jsp" />

</portlet:actionURL>


<aui:form action="<%= editGreetingURL %>" method="post">

        <aui:input label="greeting" name="greeting" type="text" value="<%=

    greeting %>" />

        <aui:button type="submit" />

</aui:form>


<portlet:renderURL var="viewGreetingURL">

        <portlet:param name="mvcPath" value="/view.jsp" />

</portlet:renderURL>


<p><a href="<%= viewGreetingURL %>">&larr; Back</a></p>


4) deploy 해서 확인해 볼 수 있다. 



<참조>

  - 포틀릿 해부하기 

  - 포틀릿 수정하기 

  - 포틀릿 2 Phase Execution

  - pom.xml 파일 샘플 

pom-userxxx-liferay.xml

posted by 윤영식