Menu

Liferay 6.2: Tạo Portlet đầu tiên

Portlet hay ta có thể gọi là các ứng dụng sẽ được cắm vào công thông tin của chúng ta. Đây sẽ là nơi cho các lập trình viên phát triển các ứng dụng của mình. Trong bày này, chúng ta sẽ tìm hiểu các công cụ phát triển portlet trong Liferay và tạo ra một portlet đơn giản, triển khai (deploy) và "gắn" vào trong cổng thông tin của chúng ta.
Trong phần này, chúng ta quan tâm tới phần phát triển. Như đã giới thiệu ở bài trước, chúng ta có ba thành phần cần quan tâm là portal, IDE và SDK. Chúng ta mới sử dụng portal, còn IDE và SDK thì chưa nói gì cả.
  • SDK:  ta sử dụng phiên bản 2.2.1 GA2, sau khi tải về bạn giải nén ra (tốt nhất nên giải nén vào cùng thư mục với thư mục portal), ta được thư mục mới là liferay-plugins-sdk-6.2. Ta sẽ xem nó có những gì nhé:
Cấu trúc thư mục của SDK:
liferay-tutorial
     |__liferay-plugins-sdk-6.2
          |___clients
          |___dist
          |___ext
          |___hooks
          |___layouttpl
          |___lib
          |___misc
          |___portlets
          |___themes
          |___tools
          |___webs
          |___build.properties
          |___build.<username>.properties
          |___build.xml
          |___build-common.xml
          |___build-common-plugin.xml
          |___build-common-plugins.xml
Trong đó:
clients: chứa các ứng dụng người dùng
dist: chứa các ứng dụng được đóng gói (có lệnh ant giúp ta đóng gói các ứng dụng)
ext: chứa các plugin dạng extension
hooks: chứa các ứng dụng hook (hook là gì sẽ nói sau nhé)
layouttpl: chứa các mẫu layout
lib: thư viện chung
misc: chứa các file cấu hình
portlets: chứa các portlet mà chúng ta phát triển
themes: chứa các theme được phát triển
tools: chứa các công cụ tiện ích và các mẫu
webs: chứa các plugin dạng web
build.xml: là file cấu hình của ANT, trong file này chứa các target dùng để phát triển ứng dụng sau này. Các target thường gặp:
    • build-service: tạo ra lớp dịch vụ cho ứng dụng (sử dụng Liferay Service Builder)
    • compile: biên dịch mã nguồn
    • deploy: triển khai ứng dụng vào máy chủ
    • ...
  • IDE: bạn click vào đây để xem IDE của Liferay. Chúng ta thấy rằng, có hai IDE là Liferay Developer Studio và plugin IDE của Eclipse. Liferay Developer Studio cũng chính là eclipse nhưng được cài cắm thêm các công cụ và do đó sẽ mất phí. Tự chung lại, nếu bạn quen sử dụng IDE Eclipse là tốt nhất còn không thì cũng không khó khăn gì với hướng dẫn chi tiết của mình ở những bài sau. Đối với plugin của elipse bạn có thể download bản eclipse có cài sẵn Liferay IDE hoặc bạn tải Eclipse riêng và Liferay IDE rieeng. Mình khuyên nên download bản tích hợp cho đỡ mất thời gian.
Sau khi tải IDE về, bạn giải nén ra thư mục cùng với portal và sdk. Ta được thư mục eclipse. Lúc này bạn, click vào file eclipse.exe (đối với window), eclipse (đối với Linux). Khi eclipse khởi động xong, ta sẽ thực hiện cấu hình:
  • Workspace: bạn có thể đặt workspace của eclipse ở đâu cũng được, nhưng tốt nhất là bạn tạo thư mục workspace trong cùng thư mục với eclipse.
  • SDK: Bạn vào Windows >> Preferences và chọn Liferay.
Cấu hình Eclipse sử dụng plugin Liferay
Chúng ta thấy có 3 thứ cần cầu hình i) Configure installed Liferay Plugsin SDKs, ii) Create a new Liferay runtime environment và iii) Create a new Liferay Server.
Click vào Configure installed Liferay Plugsin SDKs >> Add >> Browse
Cấu hình SDK
Chúng ta sẽ chọn thư mục SDK vừa giải nén ban nãy và nhấn vào nút OK.
  • Server Runtime: Bước này chúng ta sẽ cài đặt Server Runtime. Trở lại bước trước, bạn click vào Create a new Liferay runtime environment, một cửa sổ mới mở ra, chúng ta sẽ chọn server tomcat tương ứng với bản tomcat trong portal. Chúng ta sử dụng liferay phiên bản 6.2 nên bạn chọn Liferay v6.2 CE (Tomcat 7).
Bạn tích vào Create a new local server thì sẽ thực hiện luôn cả bước 3. Ở đây, mình tách ra từng bước một để dễ hướng dẫn. 
Cấu hình Server Runtime
Tiếp theo, chúng ta click vào Next và chọn Browse...
Tại đây, chúng ta sẽ chọn thư mục tomcat trong thư mục portal. Runtime JRE thì chọn mặc dịnh của máy (ở đây mình cài Oracle JDK phiên bản 1.7- nếu sử dụng phiên bản 1.8 đôi lúc build ứng dụng bị lỗi, hiện mình cũng chưa biết tại sao bị thế.) Bạn nhấn vào nút Finish.
Chọn tomcat server
  • Tạo server: trở lại bước trước, bạn click vào Create a new Liferay server. Bạn chỉ cần chọn mặc định và nhất vào nút Next.
Tạo mới server
Ở giao diện tiếp theo, chúng ta sẽ chọn các ứng dụng để triển khai trên máy chủ. Nhưng vì chúng ta chưa có ứng dụng nào nên bạn nhất Finish để kết thúc việc tạo mới máy chủ.

Vậy là ta đã cầu hình xong, ở giao diện eclipse bạn chọn Windows >> Open Perspective >> Liferay để vào giao diện mặc định.
Giao diện lập trình
Bạn click vào nút Start (khoanh màu đỏ) để khởi động máy chủ. Trước đây, chúng ta khởi động máy chủ bằng cách click vào file startup.bat hoặc catalina.sh, nhưng giờ chúng ta có cách khác, các thông báo của máy chủ sẽ hiện thị trên console của eclipse cho bạn theo dõi hoạt động của máy chủ.
Đợi một lúc, máy chủ khởi động thành công chúng ta sẽ đi tạo ứng dụng đầu tiên.

Tạo ứng dụng
Chúng ta có thể kể đến các ứng dụng mà chúng ta có thể phát triển như portlet, hook, theme, ext, layout,... Nhưng hãy khoan bàn đến những cái xa vời, trước hết chúng ta chỉ quan tâm tới portlet, và ở đây khi nó đến ứng dụng nghĩa là nói đến portlet nhé.
SDK cung cấp công cụ để chúng ta tạo ra các ứng dụng trên giao diện console, nhưng ta có thể bỏ qua không quan tâm đến việc sử dụng giao diện dòng lệnh để làm việc vì vừa mất thời gian và dễ nhầm lẫn. Chính vì vậy, từ này về sau chúng ta chỉ quan tâm đến việc phát triển ứng dụng bằng giao diện đồ họa mà thôi (nếu bạn muốn dùng giao diện dòng lệnh thì vào hướng dẫn chi tiết của Liferay nhé).

Như mọi phần mềm được phát triển bằng công cụ Eclipse, chúng ta sẽ tạo mới một dự án. Thứ tự thực hiện như sau:
  1. Bạn chọn File >> New >> Liferay Plugin Project.
  2. Điền thông tin vào ô Project NameDisplay Name
  3. Sử dụng User Default Location nhé, chúng ta sẽ thấy rằng project được tạo sẽ lưu vào trong thư mục portlets (themes, hooks, hay exts) trong sdk, bạn đừng thay đổi đường dẫn này, vì các công cụ dịch trong sdk chỉ làm việc nếu bạn để project đúng chỗ.
  4. Build Type: ở đây mình dùng quen ANT nên mình chọn là Ant, còn nếu bạn dùng quen MAVENT thì bạn có thể chọn tùy ý.
  5. Plugins SDK: là SDK mà chúng ta đã cấu hình ở trên
  6. Liferay Runtime: chúng ta chọn loại đã cấu hình ở trên
  7. Select the plugsin type: chúng ta chọn loại tương ứng, mình đang hướng dẫn tạo portlet nên mình chọn portlet.
  8. Bạn click vào nút Next để chuyển sang bước tiếp.
Tạo plugin project
Chuyển sang bước kế tiếp:
Liferay MVC
Bạn tích vào Liferay MVC (Model-View-Controller) mà một mô hinh đơn giản, để hiểu và nhấn vào nút Finish. Bạn đợi một lúc, SDK đang tải các thư viện về và sau đó sẽ tạo project cho bạn.
Như vậy, ta đã có một project mới có tên là First-App-portlet. Bây giờ, bạn click chuột phải vào tên First-App-portlet và chọn New >> Liferay Portlet.
Thêm mới portlet vào project
Ở đây, chúng ta sẽ thêm portlet mới vào dự án First-app.

  • Portlet class: là tên class của portlet, hay chính là thành phần C (Controller) tron mô hình MVC. Phần này sẽ đảm bảo tương tác giữa giao diện (JSP) và lớp service.
  • java packeage: tên gói chủa Portlet class
  • supper class: vì ở đây chúng ta chọn mô hình MVC nên bạn cọn class com.liferay.util.bridges.mvc.MVCPortlet
và nhấn vào nút Finish.

Sau khi tạo thành công Project đầu tiên, bạn phải thêm project đó vào trong server. Đề làm điều này, bạn click chuột phải vào máy chủ liferay (ô màu đỏ)
Thêm ứng dụng vào máy chủ
và chọn Add and Remove.
Thêm và xóa ứng dụng
Bên trái là danh sách các ứng dụng (portlet, theme, ...) chưa thêm vào trong máy chủ. Bên phải là danh sách các project đã được thêm vào máy chủ. Ở đây, chúng ta có project đầu tiên, chưa được thêm vào máy chủ. Bây giờ bạn click vào project (First-App-portlet) và sau đó nhấn vào nút "Add" và sau đó nhấn vào nút Finish.
Như vậy, ta đã thêm được project của mình vào trong máy chủ. Công việc bây giờ là khởi động máy chủ và chờ xem kết quả nhé (bạn biết cách khởi động máy chủ từ eclipse rồi chứ ?), nếu khi chạy mà có những thông báo bất thường hoặc ngoại lệ thì bạn cần xem lại. Nếu dùng hệ điều hành Linux, MACOS thì có thể xảy ra lỗi liên quan đến quyền do phải đọc và ghi các file logs, temps... (bạn cấp quyền 777 cho portal nhé).
Máy chủ khởi động đã xong, bạn mởi một trình duyệt bất kỳ và vào địa chỉ: http://localhost:8080. Đăng nhập với người dùng là quản trị nhé (test@liferay.com). Lúc này, bạn xem danh sách các ứng dụng nhé (đọc lại bài này).
Thêm ứng dụng đầu tiên vào trang
Bạn nhìn thấy ô bôi đỏ chính là ứng dụng của chúng ta đẩy vào. Bây giờ bạn chỉ cần kéo nó vào trang như các ứng dụng bình thường khác.
Ứng dụng đã được thêm vào trang.
Mình đưa chuột vào ứng dụng rồi nhất "Add", ứng dụng đã được đưa vào trang như hình trên.
Bây giờ, chúng ta xe đi xem cấu trúc project của chúng ta nhé.
Cấu trúc thư mục của First-App project
Ta sẽ đi giải thích từng file và từng thư mục nhé

  • .settings: thư mục này là của eclipse, chúng ta không quan tâm
  • docroot: chứa tất cả nội dung của ứng dụng
    • css: thư mục chứa tất cả các file css của ứng dụng, bạn nên bỏ tất cả các file css nếu có vào đây nhé
    • html: chứa các file html, jsp. Chúng ta có thể thấy view.jsp là file mặc định được tạo ra. Các portlet được tổ chức thành các thư mục con.
    • js: chứa tất cả các file javascript của ứng dụng (thông thường ta có jquery hoặc các thư viện khác).
    • META-INF: không quan tâm
    • WEB-INF: chứa tất cả mọi thứ liên quan đến phần back-end.
      • classes: chứa tất cả các file được biên dịch
      • lib: chứa cá thư viện
      • src: thư mục chứa các tệp nguồn.
      • tld: chứa các file DTD 
      • liferay-display.xml: xem ở đây
      • liferay-plugin-package.properties: xem ở đây
      • liferay-portlet.xml: xem ở đây
      • portlet.xml: xem ở đây
      • web.xml:
Chúng ta sẽ đi xem một số file trong portlet
  • liferay-display.xml: File này có nội dung như sau:
<?xml version="1.0"?>
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 6.2.0//EN" "http://www.liferay.com/dtd/liferay-display_6_2_0.dtd">

<display>
<category name="category.sample">
<portlet id="first"></portlet>
</category>
</display>
Trong file này ta thấy có hai thứ cần quan tâm:
category: là phân loại của ứng dụng. Ta tạo mặc đinh ứng dụng sẽ vào loại Sample, nếu muốn tự tạo loại cho riêng mình bạn chỉ cần thay đổi thuộc tính name
của thẻ category là được.
portlet: thẻ này có thuộc tính id sẽ được sử dụng để phân biệt các portlet với nhau. id này phải giống với portlet-name trong file liferay-portlet.xml liferay.xml.

  • liferay-plugin-package.properties: chứa các thông tin cơ bản của portlet, không có ý nghĩa gì với người lập trình cả.
  • liferay-portlet.xml: noojt dung file như sau:
<?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>first</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>first-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>
Trong đó, với portlet có các thẻ như <portlet-name> tên này phải giống với giá trị của thẻ <portlet-name> trong file portlet.xml. Thẻ <icon> chứa đường dẫn đến icon của portlet. Thẻ <header-portlet-css> là đường dẫn đền file css, có thể có nheieuf thẻ này. Thẻ <footer-portlet-javascript> là đường dẫn tới các file javascript, có thể có nhiều thẻ này. Thẻ cuối cùng là <css-class-wrapper> giá trị năm trong thẻ này sẽ được thêm vào thuộc tính class trong một thẻ div ngoài cùng nhất của portlet, các file css sau này bạn nên đặt có dạng .first-portlet .abc thì có nghĩa là hiệu ứng css chỉ có tác dụng trong portlet có <css-class-wrapper> có nội dung là first-portlet. Các thẻ <role-mapper> là ánh xạ các role của liferay portal với role của portal (bạn lưu ý là cổng thông tin là một khái niệm chúng, cổng thông tin Liferay theo chuẩn của công thông tin).
  • portlet.xml: nội dung của file như sau:
<?xml version="1.0"?>

<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>first</portlet-name>
<display-name>First</display-name>
<portlet-class>com.liferay.tutorial.FirstPortlet</portlet-class>
<init-param>
<name>view-template</name>
<value>/html/first/view.jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>First</title>
<short-title>First</short-title>
<keywords></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>
Ta thấy có các thông tin về portlet như <portlet-name> chính là id của portlet, <display-name> tên hiển thị trên danh mục các portlet và <portlet-class> là tên đầy đủ của một Class, chính là controller của portlet. Mỗi portlet nên có một class controller riêng biệt nhé.
Như vậy, chúng ta đã tìm hiểu xong các file cơ bản của một portlet.
Bây giờ chúng ta sẽ chỉnh sửa portlet theo ý của chúng ta. Để đơn giản chúng ta làm phần giao diện trước nhé, phần back-end sẽ tìm hiểu ở bài tiếp theo.
Bạ mởi file html/first/view.jsp có nội dung như sau:
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:defineObjects />

This is the <b>First</b> portlet in View mode.
Ta thấy đầu ở dòng đầu tiên chính là các thư viện của portlet 2.0 sẽ được import vào trong file của chúng ta. Tiền tố prefix sẽ được dùng để gọi các thẻ khác ví dụ như: <portlet:actionURL></portlet:actionURL>, actionURL là một thẻ trong portlet 2.0 vì ta định nghĩa prefix là portlet nên tên của actionURL có dạng portlet:actionURL, ngoài ra chúng ta có thể import nhiều taglib nhưng dần dần mình sẽ giới thiệu các taglib này cho các bạn, khi nào dùng cái này, khi nào dùng cái khác. Nhưng chắc chắn một file jsp phải có ít nhất một taglib như trên.
Dòng thứ hai theo chuẩn JSR 286 thì thẻ này sẽ định nghĩa một số biến toán cục: như renderRequest, renderResponse, resourceRequest, resourceResponse, actionRequest, actionResponse, eventRequest, eventRestponse, portletConfig, portletSession, portletSessionScope, portletPreferences và portletPreferencesValeus.
Dòng thứ ba là một dòng html thông thường.
Bây giờ chúng ta sửa lại view.jsp thành như sau:
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:defineObjects />

This is my first Liferay Portlet
Bây giờ ta sẽ deploy ứng dụng của chúng ta và xem những sửa đổi của chúng ta nhé. Hiện tại, máy chủ đang để ở chế độ tự động deploy mỗi khi có chỉnh sửa, điều này sẽ làm tốn tài nguyên của chúng ta, để tắt chế độ này bạn double click vào máy chủ và vào phần publishing và chọn Never publish automatically
Tắt chế độ tự động deploy
Sau khi tắt chế độ này, mỗi lần muốn deploy ứng dụng bạn chỉ cần click vào ứng dụng tương ứng ở server và chọn redeploy là được.
Deploy ứng dụng
Sau khi deploy ứng dụng, chúng ta sẽ thấy ứng dụng thay đổi trên màn hình bằng cách reload lại mạn hình của trình duyệt, ta được như sau:
Ứng dụng sau khi thay đổi.
Như vậy, bài hôm nay khá là dài, từ cấu hình môi trường lập trình cho đến tạo ứng dụng đầu tiên. Đây là ứng dụng đơn giản nhất và bạn có thể tải về từ github.
Lưu ý, các ví dụ sau này mình sẽ upload lên github để các bạn tiện theo dõi nhé. Địa chỉ tại đây.
Have a nice day!

2 nhận xét:

  1. Trả lời
    1. Cảm ơn @Khoa Nguyen,
      Mong bạn ủng hộ và cho những ý kiến tích cực để nâng cao chất lượng của các bài viết.
      Thanks!

      Xóa