포틀릿이란 무엇인가?

WEB 2008. 12. 2. 11:29 |

포틀릿이란 무엇인가? Part 1.

(http://www.onjava.com/pub/a/onjava/2005/09/14/what-is-a-portlet.html)

 

by Sunil Patil

09/14/2005

 

Portlets

포틀릿은 복합페이지의 컨텍스트내에 결집되기 위해 특별히 고안된 웹컴포넌트이다. 통상 많은 포틀릿들은 포탈페이지의 단일 요청(request)로 호출된다. 각 포틀릿은 마크업 조각을 생성한다. 그것은 다른 포틀릿의 마크업과 겹합되어 전체 포탈페이지 마크업이 된다. (JSR 168 포틀릿 스펙중)

 

이 기사는 다음의 주제들을 다룬다:

 

1. 포탈 페이지의 요소

2. 포탈이란 무엇인가?

3. 포틀릿이란 무엇인가?

4. "Hello World" 포틀릿 개발하기

5. Pluto "HelloWorld" 배치하기(Deploy)

6. 포탈페이지는 어떻게 생성되는가?

7. 결론

8. 참고자료

 

포틀릿스펙은 포틀릿을 "요청의 처리 및 동적 컨텐츠를 생산하는 포틀릿 컨테이너에 의해 관리 되어지는 자바기술기반의 웹컴퍼넌트" 정의하고 있다. 위의 정의로는 포틀릿에 대해 이해하기가 쉽지 않다. 이 기사는 포틀릿이 무엇이며 무엇을 하는지 설명한다.

 

   Figure 1. 일반적인 포탈서버 컨텐츠(WebSphere Portal 5.1)

 

브라우저 컨텐츠를 자세히 들여다 보면 이 페이지는 다른 여러개의 "윈도우"구성된것을 발견할 수 있을 것이다. 한 윈도우는 날씨정보를 갱신하고, 다른 윈도우는 뉴스를 보여준다. 또다른 윈도우는 증권시세를 실시간으로 갱신하는등 다양한 윈도우들이 있다. 이런 각 윈도우들은 포틀릿을 보여준다. 더 자세히 보면 각 윈도우는 타이틀바와 최소화, 최대화등 몇개의 버튼들로 구성되어 있는것을 발견할 수 있을 것이다.

 

한 페이지에서 이 윈도우들은 각기 독립적으로 개발된 다른 어플리케이션들 이다. 뉴스 포틀릿 개발자는 어플리케이션을 만들고 .war파일도 압축한다. 그러면 포탈서버의 관리자는 .war파일을 서버에 설치하고 페이지를 생성하게 된다. 다음 단계로 모든 사용자는 자신의 페이지에 필요한 어플리케이션을 선택할 수 있게 된다. 예를들어, 만일 사용자가 증권시세에 관심이 없고 스포츠정보에 관심이 있다면 "Stock Update"윈도우를 "Sports Update" 윈도우로 교체할 수 있다.

 

포틀릿 기술은 많은양의 새로운 개념에 대한 학습을 필요로 한다. 이 기사에서 이 모든것을 다루는것은 불가능하다. 그러므로 이 기사는 두 부분으로 나누어 연재할 것이다. 이 기사에서는 포탈과 포틀릿에 대해 정의하고 간단한 "Hello World"포틀릿을 개발해볼 것이다. 그리고 더 발전된 주제에 관해서는 다음장에서 다룰것이다.

 

여기서는 Apache Pluto server(Portlet API 1.0구현)로 샘플 포틀릿들을 테스트할 것이다. 물론, Pluto server의 설치와 사용법에 관해서도 다룰것이다.

 

포탈 페이지의 요소

 

Figure 2는 포탈페이지의 다양한 요소들을 보여준다.

     [[Figure 2. 포탈페이지의 요소들]]

 

모든 포탈페이지는 하나이상의 포틀릿 윈도우로 만들어진다. 모든 포틀릿 윈도우는 두가지 부분으로 구분할 수 있다: 하나는 타이틀바, 아이콘(Controls), 포틀릿윈도우의 두께(Border)같은것들을 어떻게 표현할 것인지 결정하는 "장식(decoration)"포틀릿 어플리케이션에 의해 제공되어지는 "포틀릿 조각(fragment)" 부분이다.

 

포탈서버는 로고, 타이틀바 컨트롤의 색상 이미지등 포탈페이지 전반의 룩앤필(look and feel)을 결정해야 한다. 몇개의 JSP .css(stylesheet)의 변경으로 포탈 전체의 룩앤필을 변경할 수 있다. 더 자세한 사항은 "포탈페이지는 어떻게 생성되는가?"란에서 다룰것이다.

 

포탈이란 무엇인가?

 

포틀릿을 이해하기 위해서는 먼저 포탈이 무엇인지 이해하는것이 필요하다. 포틀릿스펙에 따르면 "포탈은 개인화, 싱글사인온, 다른 소스와 호스트의 정보시스템 프레젠테이션층 정보를 집적하는등의 기능을 공통적으로 제공하는 웹어플리케이션이다. 집적(aggregation)웹페이지에서 다른소스로 부터 컨텐츠를 통합하는 행위를 말한다." 라고 정의하고 있다.

 

포탈기능은 세가지 주요부분으로 구분될 수 있다:

 

1. 포틀릿 컨테이너: 포틀릿 컨테이너는 서블릿 컨테이너와 매우 유사하다. 포틀릿들은 포틀릿 컨테이너 내부에 배치(deploy)되며 포틀릿 컨테이너는 포틀릿의 생명주기(life cycle) 제어하며 필요로하는 자원정보를 제공한다. 포틀릿 컨테이너는 포틀릿을 초기화(initializing)하고 제거(destroying)하며 사용자의 요청을 전달하고 응답을 수집할 의무가 있다.

 

2. 컨텐트 집적자(aggregator): 포틀릿 스펙 정의에 따르면 포탈의 주된 작업중 하나는 다양한 포틀릿 어플리케이션들에 의해 생성된 컨텐츠를 집적하는 것이다. 여기에 대한 자세한 사항은 "포탈페이지는 어떻게 생성되는가?"란에서 다룰것이다.

 

3. 공통 서비스: 포탈서버의 주요 강점중 하나는 제공되어지는 공통서비스이다. 이 서비스들은 포틀릿스펙의 일부가 아니다. 그러나, 상업용 포탈 제품를은 경쟁제품들과 차별화된 풍부한 공통서비스들을 제공하고 있다. 대채로 구현되길 희망하는 공통서비스들은 다음과 같다:

 

* 싱글사인온(Single sign on): 포탈서버에 한번 로그인 함으로서 다를 모든 어플리케이션의 접근권한을 가지는것. 이것은 모든 어플리케이션에 일일이 로그인하지 않아도 된다는것을 의미한다. 예를들어, 인트라넷에 로그인 했다면 메일어플리케이션이나 메신저, 다른 인트라넷 어플리케이션에 별도로 로그인할 필요가 없다는것을 의미한다.

 

포탈서버는 보안된 "신용정보 저장소(credentials store)" 제공한다. 사용자가 메일어플리케이션에 접근할때 사용자명과 암호를 입력한다. 이 정보는 암호화된 형태로 credentials store저장될것이다.다음부터, 사용자가 인트라넷에 로그인 할경우 포탈서버는 사용자의 신용정보를 저장소에서 읽어서 사용자 대신 메일서버에 로그인 시켜준다. 다른 어플리케이션에 대해서도 마챦가지로 작동한다.

 

* 개인화(Personalization): 기본적인 개인화서비스의 구현을 사용자가 자신의 페이지를 두가지 방식으로 커스터마이징할수 있도록 허용한다. 첫번째로, 사용자는 자신이 원하는 색깔로 타이틀바를 변형하고 컨트롤아이콘을 변경할 수 있다. 두번째로, 사용자는 자신의 페이지에 표시되길 원하는 포틀릿을 결정할수 있다. 예를들어, 난 굉장한 스포츠팬이다. 난 아마도 증권정보와 뉴스 포틀릿을 내가 좋아하는 팀의 최신정보를 갱신하는 포틀릿으로 변경할 수 일을것이다.

 

몇몇 상업용 제품들의 경우 개인화 서비스에서 어플리케이션이 사용자의 수입이나 관심사와 같은 기준에 따라 허용유무를 결정하는 경우도 있다. 예를들어, 관리자는 "사용자의 수입이 얼마 이상인 경우에만 프리미엄제품 포틀릿을 보여줘라" 또는 "수입이 얼마 인경우 할인제품 포틀릿을 보여줘라" 는 식의 비지니스룰을 생성할 수 있다.

 

그밖에 추가로 "machine translation"과 같은 서비스도 있다. 이것은 포탈서버가 포틀릿에서 생성한 한가지 유형의 정보를 사용자가 지정한 언어로 번역하여 제공하는 것이다. 대부분의 상업용 포탈서버들은 이동기기나 브라우저에 의한 호환성에 따른 "machine translation"서비스를 제공한다.

 

포틀릿이란 무엇인가?

 

서블릿과 유사하게 포틀릿은 포틀릿컨테이너에 배치되어 동적 컨텐츠를 새성하는 웹컴포넌트이다. 기술적 측면에서 포틀릿은 javax.portlet.Portlet 인터페이스를 구현하는 클래스이며 포틀릿컨테이너에 .war파일형태로 압축되어 배치된다.

 

포틀릿은 다음과 같은 측면에서 서블릿과 유사하다:

 

1. 포틀릿은 특정컨테이너에 의해 관리되어진다.

2. 포틀릿은 동적인 컨텐츠를 생성한다.

3. 포틀릿은 컨테이너에 의해 생명주기가 관리되어진다.

4. 포틀릿은 웹클라이언트와 요청/응답 패러다임을 통해 작동한다.

 

포틀릿은 다음과 같은 측면에서 서블릿과 다르다:

 

1. 포틀릿은 전체 문서가 아니라, 마크업 조각(fragment)만을 생성한다.

2. 포틀릿은 직접경로(URL)을 제공하지 않는다. URL에 의해 포틀릿만을 단독으로 호출하는것은 불가능하며 포틀릿을 포함하고 있는 페이지의 URL을 호출하여야 한다.

3. 포틀릿이 생성한 컨텐츠는 포탈페이지의 일부이기 때문에 포틀릿은 자의적인 컨텐츠를 생성할 수 없다. 만약, 포탈서버가 text/html형식을 제공한다면 모든 포틀릿은 text/html 컨텐츠만 생성하여야 한다. 반대로, 포탈서버가 WML형식을 제공한다면 각 포틀릿들 또한 WML컨텐츠를 생성해야 한다.

 

포틀릿들은 몇가지 부가적인 기능을 제공한다.

 

1. 환경설정을 위한 영속저장소: 포틀릿은 PortletPreferences객체늘 사용자의 환경정보를 저장하기위해 제공한다. 이 환경정보는 영속 저장소에 저장되어 이용가능하다. 개발자는 이것이 어떻게 저장되는지  몰라도 상관없다.

 

2. 요청처리: 포틀릿은 더욱 정련된 요청처리를 한다. 사용자가 포틀릿에 어떤 행동을 취하거나(action 단계) 다른 포틀릿에 행동을 취한경우와 페이지가 refresh된경우 포틀릿은 요청을 받게 된다. 이때 포탈서버는 이 두가지 상황을 처리하기 위해 다른 콜백 메소드를 제공한다.

 

3. 포틀릿 모드: 포틀릿은 사용자가 무엇을 하고있는지를 가리키기 위해 모드(mode)개념을 사용한다. 메일 어플리케이션을 사용할때, 사용자는 메일을 읽고, 작성, 확인하는등의 기본적인 기능들을 사용한다. 포틀릿들은 일반적으로 이러한 기능을 VIEW 모드로 제공한다. 그러나, refresh time설정이나 사용자명, 비밀번호를 재설정하는것과 같은 행위도 있다. 이런 사용자가 어플리케이션의 상태를 설정 하는것을 허가한 경우 EDIT 모드로 제공된다. 도움말 기능은 HELP 모드로 진행된다.

 

모든 VIEW모드와 관련된 비지니스로직과 관련된 사항들은 doView()메소드에 넣어두고 어플리케이션 설정과 관련된 비지니스로직은 doEdit()메소드에 둔다. 도움말 관련 로직은 doHelp()메소드에 둔다.

 

이러한 작업은 관리자가 포틀릿어플리케이션에 접근을 제어하는것은 단순하게 한다. 이렇게 되면 관리자는 사용자에게 무엇을 허가 할것인지 포틀릿에대한 접근권한만 변경하면된다.  예를들어, 메일어플리케이션 사용자가 EDIT모드에서 사용자명과 암호를 입력하는 것은 사용자에게 EDIT모드에 접근권한이 주어졌음을 의미한다.

 

다음의 경우를 가정해보자. 나는 인트라넷사이트의 관리자이고 회사에서 뉴스정보를 갱신하는 써드파티 포틀릿을 구매하였다. 이 어플리케이션을 사용자가 뉴스정보를 어디서 가져올지 URL을 지정할 수 있도록 허락한다. 나는 이 뉴스포틀릿이 사내뉴스정보를 갱신하도록 하고 사용자가 다른 소스로부터 뉴스를 가져오는것을 허가하고 싶지 않다. 이럴경우 관리자로서 나는 모든 사용자에게 사내뉴스사이트를 URL로 등록하고 포틀릿어플리케이션의 배치지시자(deployment descriptor)를 변경하여 사용자로 부터 수정 권한을 박탈할수 있다.

 

포틀릿을 웹사이트에 적용 하는것은 사용자가 다른 모든 포틀릿 어플리케이션들로부터 유사한 사용자 인터페이스를 제공받으므로 사용자에게 더욱 호감을 준다. 사용자는 어떤 어플리케이션의 도움말을 보고 싶다면 도움말버튼을 클릭할 것이다. 또한 어플리케이션의 환경설정을 변경하기 위해서는 EDIT 버튼을 클릭해야 한다는 사실도 이미 알고있을것이다. 사용자 인터페이스를 표준화 하는것은 포틀릿 어플리케이션을 더욱 호감이 가도록 만들것이다.

 

4. 윈도우 상태: 윈도우 상태는 포탈페이지상에서 포틀릿이 생성한 컨텐츠가 얼마만큼의 공간을 차지 할지를 결정한다. 사용자가 최대화버튼을 클릭할경우 포틀릿은 전체 스크린을 차지하게 될것이다. 최소화버튼을 클릭할경우 포틀릿은 타이틀바만 표시될 것이다. 개발자는 컨텐츠의 양을 기준으로 크기를 적절히 조정해야 한다.

 

5. 사용자 정보: 공통적으로, 포틀릿은 사용자에게 개인화된 컨텐츠를 제공한다. 이것을 효과적으로 처리하기 위해 포틀릿은 이름, 이메일, 전화번호와 같은 사용자의 속성정보에 대한 접근을 필요로 한다. 포틀릿 API이를위해 사용자속성(user attribute)개념을 제공한다. 개발자는 이 속성정보에 표준적인 방법으로 접근할 수 있으며 관리자는 이 속성정보가 실제 사용자정보 저장소와 일치(mapping)시킬 책임이 있다.

 

다음장에서 이런 기능들(요청처리, 사용자정보, 포틀릿모드)에 대해 자세히 다룰것이다.

 

"Hello World" 포틀릿 개발하기.

 

이제 HelloWorld 포틀릿을 개발할 시간이다.

 

1. HelloWorld 웹 프로젝트를 생성한다. 이것은 일반적인 서블릿 프로젝트와 유사하다. 이것은 배치지시자(deployment descriptor) /WEB-INF/web.xml 파일을 가진다.

 

2. portlet-api-1.0.jar 파일을 클래스패스에 추가한다. (pluto 배포판에 포함되어 있다.)

 

3. 소스폴더에 HelloWorld.java를 다음과 같이 생성한다.

 

public class HelloWorld extends GenericPortlet{

  protected void doView(RenderRequest request,

  RenderResponse response) throws

  PortletException, IOException {

        response.setContentType("text/html");

        response.getWriter().println("Hello Portlet");

        }

}

 

모든 포틀릿은 Portlet인터페이스를 구현하여야 한다. 이 인터페이스는 포틀릿의 생명주기 메소드를 정의하고 있다. 메소드들을 모두 구현하지 않으려면 GenericPortlet을 확장하면 된다. 이 클래스는 Portlet 인터페이스를 구현하는 어댑터 클래스이다. 이것은 기본적인 생명주기 메소드를 제공하므로 필요한 메소드만 다시 구현하면 된다.

 

HelloWorld포틀릿는 "Hello Portlet" 출력하는것이 전부이다. 그러므로, doView()메소드만 오버라이드 할것이다. 메소드는 PortletRequest PortletResponse를 인수로 받는다. doView()메소드에서 맨처음 해야할일은 respoinse.setContentType()을 호출하여 포틀릿컨테이너에게 어떤 컨텐츠타입이 생성될지 알리는 것이다. 실패할경우 IllegalStateException이 발생한다. 컨텐츠타입이 설정되면 response객체로 부터 PritWriter를 가져와 출력을 한다.

 

4. 모든 포틀릿 어플리케이션은 /WEB-INF/디렉토리에 portlet.xml을 포함해야 한다. 이것은 포틀릿을 위한 배치지시자(deployment descriptor)이다. portlet.xml을 다음과 같이 작성한다:

 

<portlet>

  <description>HelloWorldDescription

        </description>

    <portlet-name>HelloWorld

        </portlet-name>

    <display-name>Hello World

        </display-name>

 

    <portlet-class>com.test.HelloWorld

        </portlet-class>

    <expiration-cache>-1

        </expiration-cache>

        <supports>

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

      <portlet-mode>VIEW

          </portlet-mode>

        </supports>

    <supported-locale>en

        </supported-locale>

 

        <portlet-info>

          <title>Hello World</title>

          <short-title>Hello World

          </short-title>

          <keywords>Hello,pluto</keywords>

      </portlet-info>

</portlet>

 

<portlet-name>요소는 포틀릿의 이름을 정의한다. <portlet-class>요소는 패키지를 포함한 포틀릿의 클래스명을 기술한다. <expiration-cache>요소는 컨텐츠의 유효기간을 초단위로 기술한다. 만일 포틀릿에 어떤 행위를 하게되면 캐쉬시간은 무시되고 새로운 컨텐츠가 생성된다.

 

<support>요소는 주어진 <mime-type>을 위해 지원되는 모드를 기술한다. 앞의 예제에서 HelloWorld text/html컨텐츠만 생성하였다. 만일 다른 컨텐츠타입을 지원하려고 한다면 해당 컨텐츠타입이 지원할 모드를 새로운 <support>요소에 기술해야 한다. 일반적인 포틀릿들은 text/html을 위해 VIEW, EDIT, HELP 모드를 지원하고 WML 마임타입을 위해서는 VIEW만 지원한다.

 

포틀릿이 어떤 로케일을 지원할지 <supported-locale>요소에 기술한다. <title>요소는 포틀릿에 표시할 제목을 의미한다. 다국어환경의 경우 <resource-bundle>요소에 리소스파일명을 기술하여야 한다. 포틀릿 컨테이너는 사용자의 로케일에 기반하여 해당 리소스에서 제목을 가져올 것이다.

 

5. 모든 포틀릿 어플리케이션을 웰어플리케이션과 동일하므로 portlet.xml과 함께 web.xml도 필요로 한다.

 

<web-app>

  <display-name>Hello World Portlet

  </display-name>

  <welcome-file-list

    <welcome-file>index.jsp

        </welcome-file>

  </welcome-file-list>

</web-app>

 

6. 다음 단계는 컴파일과 .war 패키징 하는것이다. (build.xml을 이용해서 build하거나 Resources 섹션에서 다운로드 하라.)

 

 

HelloWorld 포틀릿 배치하기

포탈페이지는 어떻게 생성되는가?

*************************************************************************************

(참고) 이 기사는 Pluto 1.0.x 버젼 기준으로 작성되어 Pluto 1.1 deploy환경에 차이가

있어 포틀릿의 배치와 포탈페이지 생성에 관한 부분은 번역을 생략한다.

pluto 1.1에서 portlet deploy하는 방법은 아래의 Pluto Website를 참고하라.

 

http://portals.apache.org/pluto/deploying.html

*************************************************************************************

 

결론

 

어떤 새로운 기술이 성공하기 위해서는 몇가지 퀄리티가 요구된다:

 

첫째, 이것은 기존에 존재하는 기술을 활용할 수 있어야 한다.

둘째, 이것은 기존의 기술이 가진 공통된 문제점을 해결할 수 있어야 한다.

셋째, 이것은 하나이상의 추상레이어를 제공해야 한다.

 

포틀릿API서블릿기술이 빛을볼수 있는 매우좋은 기회이다. 왜냐하면, 이것은 기존에 존재하는 인프라스트럭쳐를 활용하기 때문이다. 포틀릿은 EJB를 호출하거나 어플리케이션서버에 의해 제어되는 트랜잭션에 참여하거나 시작할 수 있다. 다시말해, 포틀릿은 서블릿이 할수 있는 비지니스로직  중심의 모든일을 할수 있다는것을 의미한다.

 

포틀릿은 추상화레이어를 함께 제공한다. 당신은 더이상 클라이언트의 어떤 HTTP메소드가  사용되어 졌는지 또는 버튼 클릭과 같은 이벤트를 받기위해 특정 인프라스트럭쳐를 만들어야 할지 걱정할 필요가 없다. 마침내, 포틀릿은 싱글사인온, 개인화서비스등을 제공하여 서블릿이 가진 대부분의 공통된 문제점들을 해결했다.

 

번역: 원찬

03/31/2006

: