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

Publication

06-15 06:12

Category

Recent Comment

포틀릿을 생성하고 세부사항에 대하여 알아보고, 포틀릿의 두가지 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 peter yun 윤영식
2014. 4. 30. 17:28 Study Frameworks/Liferay Portal

Liferay 포털의 개발은 결국 기존 플러그인들의 확장 및 신규 개발 관건이다. 툴에 대한 이해를 하고 설치 사용해 보자 



Liferay IDE

  - Eclipse 플러그인으로 Eclipse Market에서 검색하여 설치가능 : "liferay ide"

  - Plugin SDK 또는 Maven과 Liferay runtime 환경과 결합하여 개발한 것을 배포 테스트 가능케 해준다  

  - Eclipse Indigo(3.7.x), Juno(4.2.x), Kepler(4.3.x) 에서 설치가능 

  - Plugin SDK와 Runtime 환경 설정 블로깅 참조 



Liferay Project 생성 

  - Eclipse의 Liferay IDE Perspective를 띄운다 

  - "New" -> "Liferay Plugin Project"를 선택한 후 하기와 같이 입력하고 "Service Builder"를 선택하고 생성한다 

    

  - 프로젝트 생성 내역

> docroot : 실제로 서비스하는 영역이다 

> view.jsp : 포틀릿으로 보여지는 웹 화면

> *xml : 포틀릿 설정 화면 


- liferay-display.xml 

  포틀릿 카테고리로 sample에 해당 포틀릿이 들어간다 

<display>

  <category name="category.sample">

    <portlet id="event-listing" />

  </category>

</display> 


  - 포틀릿 배포하기 

> 포틀릿을 생성하면 위치는 sdk/portlets 폴더밑으로 생성된다 


> Eclipse에서 Tomcat Server를 등록하여 기동한 상태라면 "And and New.." 컨텍스 메뉴를 선택하여 event-listing-porlet을 Add 하면 자동으로 Hot Deploy이 되어 반영된다 


- 포탈 화면에서 확인해 보자 

Sample 밑의 카테고리에 "Event Listing" 포틀릿이 존재하여 드래그앤드롭하여 원하는 위치에 놓을 수 있다


  - 프로젝트를 만든 후 기본 제공하는 항목을 제거하고 플러그인을 만들것이다. 기본 제공 설정내역을 삭제해 보자

1) WEB-INF/liferay-display.xml  에서 <portlet>..</portlet> 부분 제거 

2) WEB-INF/liferay-portlet.xml 에서  <portlet>..</portlet> 부분 제거 

3) WEB-INF/portlet.xml 에서  <portlet>..</portlet> 부분 제거  

4) view.jsp 파일 제거 


삭제까지 진행되었으면 이제 해당 프로젝트에 새로운 플러그인을 만들 준비가 되었다. 



Liferay Plugin 개발 

  - 프로젝트에는 여러개의 플러그인이 포함될 수 있다. 위에 만들어 놓은 "Event Listing" 프로젝트안에 여러개의 플러그인을 넣어본다 

  - Location Listing과 Event Listing 포틀릿 플러그인을 만들어 보자 

  - Location Listing Portlet 생성

1) 프로젝트명을 선택하고 context menu -> New -> "Liferay Portlet"을 선택하고 LocationListing 포틀릿을 입력


2) Next로 이동하여 포틀릿 정보를 입력


3) 카테고리 정보를 입력한다 "MobiconSoft"


  - event-listing 포틀릿을 생성한다 

> location-listing 과 같은 방식으로 생성

  MVCPortlet을 상속 받으면서 같은 java package에 속한다 


> 최종 생성된 Eclipse Project 모습

   + com.mobiconsoft.event의 클래스들은 MVCPortlet을 상속받아서 자동 생성된다 

   + liferay-display.xml, liferay-portlet.xml, portlet.xml 안에 위저드로 설정한 내용이 반영된다 


  - 프로젝트의 컨텍스트가 이미 Server에 반영되어서 위저드로 생성시에 Hot Deploy가 된다. 다음으로 "Mobiconsoft" 카테고리에 EventListing과 LocationListing이 반영되었는지 확인한다. 




다음 블로그에서는 "Service Builder" 도구를 사용하여 어떻게 Model, Persistence, Service Layer를 만들 수 있는지 살펴보도록 한다 


posted by peter yun 윤영식
prev 1 next