Mục LụcPhần 1: Tổng quan về portlet 31. Nhắc lại về Liferay portal 31.1 Khái niệm về portlet 41.2 Phân loại 51.2.1 JavaServer Page portlet (JSP portlet) 61.2.2 Strusts portlet 61.2.3 JavaServer Faces portlet (JSF portlet) 61.2.4 Vaadin portlet 61.2.5 Spring MVC portlet 71.3 Hoạt động của portlet trong Liferay portal 71.4 Truyền dữ liệu giữa các phase 8Phần 2: Tìm hiểu về JSP portlet và Vaadin portlet 102.1 JSP portlet 102.1.1 Cấu trúc 102.1.2 Mô hình MVC trong JSP portlet 142.1.3 Một vài đặc điểm của JSP portlet 142.2 Vaadin portlet 142.2.1 Cấu trúc Vaadin portlet 162.2.2 Hoạt động của Vaadin portlet 172.2.3 Một vài đặc điểm của Vaadin portlet 17Phần 3: Thực hành – Hướng dẫn phát triển portlet 183. Cài đặt môi trường phát triển portlet 183.1 JSP portlet 193.1.1 Firstportlet 193.1.2 MyGreetingportlet (simple) 203.1.3 MyGreetingportlet1 (Advance) 233.1.4 GreetingSessionPortlet 253.1.5 Ajax portlet 273.1.6 Report portlet 323.2 Vaadin portlet 342 | Page3.2.1 FirstVaadin portlet3.2.2 NotifyVaadin portlet3.2.3 Login portlet3.2.4 Vaadinportlet mode3.3 Project examplePhần 4: Một số vấn đề tham khảo4. Các tags phổ biến trong portlet4.1 Tùy chỉnh portlet trên giao diện4.2 Các quy ước chuẩn về codePhần 5: Phân công công việcPhần 6: Kết luậnPhần 7: Tài liệu tham khảoPhần 1: Tổng quan về portlet1. Nhắc lại về Liferay portal3 |
Trang 1TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THỒNG
-o0o -BÀI TẬP LỚN CÔNG NGHỆ WEB VÀ DỊCH VỤ TRỰC TRUYẾN
Đề tài: Phát triển portlet mới cho người dùng
Giảng viên hướng dẫn: Thầy Tạ Tuấn Anh
Nhóm thực hiện: Nhóm 04 - HTTT K52
Mai Ngọc Dương 20070009 Nguyễn Văn Minh 20071970
Trang 2Mục Lục
Trang 34 Các tags phổ biến trong portlet
4.1 Tùy chỉnh portlet trên giao diện
4.2 Các quy ước chuẩn về code
Phần 5: Phân công công việc
Trang 4Portal là: Cổng thông tin điện tử tích hợp là điểm truy cập tập trung
và duy nhất, tích hợp các kênh thông tin, các dịch vụ và ứng dụng, phân phối tới người sử dụng thông qua một phương thức thống nhất và đơn giản trên nền tảng Web
Có nhiều loại cổng thông tin khác nhau cung cấp nhiều loại dịch vụ và ứng dụng khác nhau, tuy nhiên chúng đều phải có 1 số tính năng cơ bản như:
- Khả năng cá nhân hóa (Personalization)
- Tích hợp nhiều loại thông tin (Content aggregation)
- Xuất bản thông tin (Content syndication)
- Hỗ trợ nhiều môi trường hiển thị thông tin (Multidevice support)
- Khả năng đăng nhập một lần (Single Sidn on – SSO)
- Quản trị portal (Portal administrator)
- Quản trị người dùng (Portal user management)
Chính các tính năng này là điểm phân biệt giữa một website bình thường, một ứng dụng quản trị nội dung (CMS) hay một ứng dụng chạy trên nền tảng web (Web application) với một cổng thông tin Khái niệm này hiện nay vẫn còn bị nhầm lẫn bởi rất nhiều người
Portal có các tính năng giúp người quản trị thu thập, quản lý nhiều nguồn thông tin khác nhau, từ đó phân phối chúng dưới dạng các dịch vụ cho từng người dùng khác nhau tuỳ thuộc vào nhóm quyền, vào nhu cầu cũng như mục đích của người dùng đó Portal thực hiện việc này hết sức linh động, từ những công việc như tìm xem và đặt mua sách trong một kho hàng trực tuyến, xem và thay đổi thông tin về sinh viên và giáo viên trên các ứng dụng quản lý giảng dạy, đến việc đăng và chia sẻ các thông tin, tài nguyên, bài viết trên các diễn dàn hay cung cấp việc truy cập thống nhất và thuận lợi đến các thông tin nội bộ trong một website của công ty Portal như một cổng vào vạn năng cho người dùng tìm kiếm thông tin và tác nghiệp một cách thuận lợi và dễ dàng
Khái niệm Portal đã xuất hiện từ khá lâu, trải qua một quá trình dài phát triển và hoàn thiện Liferay portal hiện đang là giải pháp cổng thông tin với mã nguồn mở toàn diện và phổ biến nhất hiện nay
1.1 Khái niệm về portlet
Portlet là một web application nhỏ chạy trong portal Nó là phần quan trọng nhất của bất kì cổng thông tin nào, bởi vì nó chứa các chức năng thực tế của portal, cụ thể hóa các chức năng đó thành giao diện tương tác với người dùng Mọi hoạt động trên portal được thực hiện thông qua các
Trang 5portlet Nói một cách khác, portlet chính là trái tim của portal.
H1 Hình ảnh về portlet tren portal (các vùng được khoanh)
Mỗi portlet chỉ là một phần nhỏ của trang web, một trang có thể bao gồm nhiều portlet Nó được biên dịch ra thành một đoạn mã HTML trong
cả trang web, vì thế, trong một portlet không bao gồm các tag như <html>,
<head> hay <body> Portal sẽ kết hợp các đoạn mã HTML đó từ nhiều portlet và gộp thành một trang web hoàn chỉnh
Nội dung sản sinh bởi 1 portlet cũng đuợc gọi là 1 fragment Một
fragment là 1 phần các ngôn ngữ đánh dấu (như HTML, XHTML, WML) tuân thủ nghiêm ngạt các luật và có thể được kết hợp với các fragments khác tạo nên 1 tài liệu hoàn chỉnh Nội dung của một portlet thông thường được tích hợp với nội dung của các portlet khác để hình thành nên trang cổng điện tử Chu kỳ sống của 1 portlet được quản lý bởi portlet container.Portlet container là thành phần quản lý các portlet của portal, nó chịu trách nhiệm quản lý, thiết lập, cung cấp tài nguyên, quản lý chu trình sống của portlet Portlet container nhận các yêu cầu từ cổng điện tử và thực thi các yêu cầu đó trên các portlet mà nó quản lý Portlet container không chịu trách nhiệm kết hợp nội dung sản sinh bởi các portlet, trách nhiệm
đó thuộc về portal Một cách khác, có thể coi portlet container là một trạm trung giam điều phối các hoạt động của portlet và portal
1.2 Phân loại
Portlet cũng có nhiều loại khác nhau và đều được Liferay portal hỗ trợ Một số loại portlet phổ biến có thể kể đến như:
Trang 6o JavaServer Page (JSP) portlets
o Struts portlets
o JavaServer Faces (JSF) portlets
o Vaadin portlets
o Spring Model–View–Controller (MVC) portlets
1.2.1 JavaServer Page portlet (JSP portlet)
Đây là loại portlet đơn giản nhất trong Liferay Phần core xử lý được viết bằng java Các nhà phát triển có thể dễ dàng hiểu và phát triển được các JSP portlet bởi cấu trúc, cách thức xử lý cũng như logic của JSP portlet
là khá đơn giản và dễ hiểu
Trong Liferay plugin SQK đã có chế độ tự động sinh các portlet theo dạng JSP portlet, coi như đây mà loại portlet mặc định
1.2.2 Strusts portlet
Strusts portlet được thiết kế theo mô hình MVC dựa trên nền tảng của Struts Portlet Framework Strust portlet là một trong những công nghệ hoàn chỉnh nhất của portlet tuy nhiên việc phát triển nó là khó khăn hơn Chúng ta có thể tải Struts portlet và Struts 2.0 portlet trên trang download của Liferay
1.2.3 JavaServer Faces portlet (JSF portlet)
Portlet được xây dựng trên nền tảng của Java Server Faces APIs của SUN Đây là công nghệ tiêu chuẩn để xây dựng giao diện người dùng phía máy chủ, được thiết kế để giúp cho các nhà thiết kế giao diện web dễ dàng hơn
Trên giao diện download của Liferay, ta có thể lấy được các WAR file cho cả JSF 1.1 và JSF 1.2 Portlet
1.2.4 Vaadin portlet
Vaadin portlet là portlet mới nhất được hỗ trợ trong Liferay portal mặc
dù chúng ta có thể chạy các phiên bản cũ bằng cách cài đặt thủ công thông qua các file thư viện mở của Vaadin
Vaadin portlet có một đặc điểm khá là thú vị bởi chúng ta viết Vaadin portlet hoàn toàn ở phía server, chúng ta không cần lo ngại về HTML, CSS, về Javascript hay sự tương thích với trình duyệt bởi nó hoàn toàn được xử lý từ bên trong Vaadin portlet được phát triển dựa trên Vaadin Framework
Trang 71.2.5 Spring MVC portlet
Liferay portal cũng hỗ trợ Spring MVC portlet Spring MVC portlet nổi tiếng với khía cạnh lập trình định hướng Được phát triển dựa trên Spring
Web Flow (SWF), Spring Framework – đây là giải pháp tốt nhất cho việc
quản lý dòng chảy trong ứng dụng web Cụ thể nó cho phép chúng ta chụp các dòng sự kiện như một module khép kín và có thể tái sử dụng cho các tình huống khác nhau Và như vậy, nó là lý tưởng cho việc xây dựng các module ứng dụng web cho phép các nhà quản lý dễ dàng quản lý các giao dịch mà không cần quan tâm đến các vấn đề xử lý ở mức độ thấp
1.3 Hoạt động của portlet trong Liferay portal
Một điểm đặc thù của portlet đó là nó cần tới 2 bước để hiển thị Nó khác biệt với rất nhiều người phát triển servlet hay những người quen sử dụng các ngôn ngữ thông dụng nhu PHP, Python hay Ruby…
Lý do cho việc phải sử dụng đến 2 phases là do portlet không phải là một trang HTML hoàn chỉnh, nó chỉ là một phần nhỏ trong cả trang Trang tin được tạo ra bằng cách gọi một hoặc một số portlet và điền các mã HTML bổ sung cho chúng để có được một trang HTML hoàn chỉnh
Tuy nhiên,việc này cũng đem lại một vài rắc rối Ta có thể hình dung quá trình hoạt động của portet và portal như sau:
Khi người dùng tương tác với trang web, chẳng hạn như bấm vào 1 link trong 1 portlet cụ thể nào đó Tất nhiên là cổng thông tin phải có trách nhiệm xử lý sự kiện đó và trả lại kết quả cho portlet Sau đó nó phải làm nhiệm vụ hiển thị cả trang web bao gồm portlet vừa tác động( nội dung của portlet này có thể đã thay đổi ), đồng thời nó phải hiện thị nội dung của
cả các portlet khác Việc này là cần thiết bởi các portlet này mặc dù người dùng không tương tác đến nhưng nội dung của nó vẫn có thể bị thay đổi bởi hành động vừa rồi của người dùng Vậy làm thế nào để cổng thông tin hiển thị được nội dung của các portlet khác khi không có bất kì tác động nào đến chúng?
Chúng ta hình dung một kịch bản: Chúng ta có một trang bán hàng với
2 portlet, một navigation-portlet (portlet cho các hình thức vận chuyển hàng) và shopping-portlet Người dùng thao tác với trang như sau:
- Người dùng vào trang bán hàng
- Click vào một button trong shopping-portlet để mua hàng Lúc này, tài khoản và giỏ hàng của người dùng đó sẽ tự động được cập nhật
và bắt đầu một quá trình để vận chuyển sản phẩm cần mua Sau khi
Trang 8hoạt động này, cổng thông tin sẽ gọi đến navigation-portlet với giao diện mặc định của nó.
- Người dùng bấm vào 1 link trong navigation-portlet để chọn kiểu vận chuyển Nội dung của portlet được thay đổi Sau đó cổng thông tin cũng phải hiển thị lại nội dung của shopping-portlet, và do đó
nó lặp lại hành động cuối của người dùng là click vào nút mua hàng một quá trình mua hàng được lặp lại dẫn đến một quá trình vận chuyển mới … Và để portlet có được nội dung của nó, nó cần phải yêu cầu lại tới portal Việc này còn có thể lặp lại nhiều lần nữa (ít nhất là cho tới khi tài khoản người dùng đến giới hạn)
Ta có thể thấy, rõ ràng là kịch bản trên là không đúng Để ngăn chặn tình huống này, các đặc điểm kỹ thuật của portlet định nghĩa 2 giai đoạn cho mọi yêu cầu của portlet để cho phép cổng thông tin có thể phân biệt được một hành động nào là đang được thực hiện (tất nhiên là không nên lặp lại)
và nội dung được sinh ra:
- Action phase: Giai đoạn này chỉ có thể được thực hiện tại 1 portlet tại 1 thời điểm và thường là kết quả của việc tương tác giữa người dùng với trang web Trong giai đoạn này, các portlet có thể thay đổi trạng thái của nó Nó cũng được đề nghị rằng có thể thực hiện các tác động như thay đổi CSDL hay các hoạt động mà không cần lặp đi lặp lại
- Render phase: Giai đoạn này luôn luôn áp dụng cho tất cả các portlet trong trang bao gồm portlet vừa tác động và cả các portlet khác Nó được thực thi khi có 1 tác động nào đó làm thay đổi đến nội dung của cả trang Có một điểm quan trọng là trong một trang, thứ tự render các portlet là không xác định Nếu cần thiết cho viện này, Liferay có một mở rộng là render-weight trong liferay-portlet.xml nhưng muốn sử dụng thì người dùng phải tự thêm vào Các portlet
có render-weight cao hơn sẽ được render trước
Như đã trình bày, portlet hoạt động trên 2 phase chính Vậy làm cách nào mà
dữ liệu hay các thông tin được truyền từ phase sang phase kia?
Có 2 cách mà ta có thể làm để truyền dữ liệu từ action phase vào render phase
Trang 9- Thứ nhất, ta có thể truyền qua các biến Trong lúc thực hiện
processAction ta có thể truyền thêm một tham số mới cho bước render:
Khi gọi một actionURL, các tham số truyền chỉ có thể đọc ở
giai đoạn action phase (trong phương thức proceessAction)
Để có thể truyền tham số cho bước render phase ta phải
lấy chúng từ actionRequest và sau đó sử dụng phương thức setRenderParamater cho mỗi tham số cần
Một chú ý quan trọng là các biến RenderParamater sẽ được portal ghi nhớ cho tới khi chính các portlet đó được gọi với tham
số khác Do đó trường hợp người dùng sử dụng portlet này và tạo ra các tham số, sau đó người dùng tiếp tục tác động đến các portlet khác, và mỗi lần trang được nạp lại, portal sẽ render lại portlet của chúng ta và sử dụng ngay các tham số được thiết lập Điều này có nghĩa là thông báo của chúng ta (giả sử đó là thông báo “Save successfuly” trong ví dụ trên) nó sẽ được hiện ra ngay
cả khi không phải chúng ta bấm Save
- Phương pháp thứ 2 là ta có thể sử dụng đó là sử dụng session Trên thực tế phương pháp này tốt hơn so với phương pháp trên Nó không chỉ truyền tham số cho một portlet mà tất cả các portlet đều
có thể lấy được Có thể mọi người đã quen với cách này khi lập trình với các ngôn ngữ khác Để thực hiện việc này, ta sử dụng thêm lớp SesionMessage được liferay cung cấp Cụ thể ta sẽ trình bày trong phần (9) Greeting-Sesion-portlet
Trang 10Phần 2: Tìm hiểu về JSP portlet và Vaadin portlet
2.1 JSP portlet
2.1.1 Cấu trúc
Trong Eclipse Liferay IDE, portlet mặc định khi tạo project là JSP
portlet, và được xây dựng dựa trên mô hình chuẩn theo MVCPortlet
Framework Nó đã ẩn đi rất nhiều phần xử lý phức tạp phía dưới portlet và giúp cho người phát triển có thể dễ dàng nắm bắt được cấu trúc, cách xây dựng và xử lý portlet mà không cần quan tâm quá nhiều đến cách xử lý bên trong
Nhìn qua 1 portlet sẽ gồm 3 phần chính:
Java sourceConfiguration fileClient-side file (.jsp, css, js, images, …)Khi sử dụng Liferay Plugin SDK để tạo portlet, cấu trúc cơ bản của thư mục chứa có dạng như sau :
Folder Structure:
H2 Portlet Structure
- Phần Java source được chứa trong thư mục docroot/WEB-INF/src
Trang 11- Các file cấu hình được chứa trong thư mục docroot/WEB-INF dưới
o liferay-portlet.xml: Tập tin mô tả một số tùy chọn của
portlet khi được cài đặt trên Liferay portal Chẳng hạn như name, display name, khai báo java class, các thư mục chứa css, js… Ta cũng có thể thấy, trong 1 project có thể chứa nhiều portlet Các portlet được khai báo lần lượt và id của nó được đặt trong file liferay-display.xml
o liferay-plugin-package.properties: Tập tin mô tả một số
đặc điểm của portlet
o portlet.xml: Tập tin mô tả cấu hình cụ thể của từng portlet
Là một người mới bắt đầu vào việc tìm hiểu portlet, chúng ta
sẽ tập trung vào tập tin này bởi nó cho ta một cái nhìn gần và
rõ ràng hơn về cấu hình tùy chọn của 1 portlet
- Các file phía client như jsp, css, javascript, image … chứa trong docroot
Để có 1 hình dung cụ thể, rõ ràng hơn về các cấu hình cho 1 portlet, ta sẽ đi vào xem xét cụ thể một số file
Trang 12portlet-id của portlet trong Liferay portal.
o display-name : Khai báo tên được hiển thị của portlet trên trang web Display-name không cần thiết phải là duy nhất
o portlet-class: khai báo class java có trách nhiệm xử lý các thao tác trên portlet
o init-param: chứa một cặp tên/giá trị như là một tham số khởi tạo của portlet Ở đây nó khai báo file hiển thị của portlet là view.jsp
o expiration-cache: Tham số này chỉ ra thời gian lưu trữ của portlet trong bộ nhớ đệm Nếu để giá trị là -1 có nghĩa là không bao giờ hết
o support: chỉ ra loại định dạng dữ liệu được hỗ trợ: mime-type Đồng thời nó cũng khai báo các “portlet-mode” để hỗ trợ cho các loại nội dung đặc biệt Tất cả các poortlet phải hỗ chợ cho “view mode” Khái niệm “portlet-mode” được định nghĩa bởi các đặc tả của portlet
o portlet-info: định nghĩa các thông tin của portlet
Trang 13o Security-role-ref: chứa thông tin về các đối tượng được phép truy cập vào Cụ thể trong liferay nó chỉ ra tên các đối tượng được truy cập vào portlet.
Liferay-portlet.xml
File chứa các thông tin bổ sung cho portlet, đó là các tùy chọn nâng cao cho các portlet java chuẩn được install trong Liferay Theo mặc định, file chứa các nội dung cụ thể sau:
<footer-portlet-javascript>/js/main.js</footer-portlet-wrapper>
Trang 14o Instanceable: thuộc tính chỉ ra khả năng có thể có nhiều portlet giống nhau trên cùng 1 trang hay không (true – có thể, false - không)
o Header-portlet-css, footer-portlet-javascript: đường dẫn đến file css
và js tương ứng
Chúng ta đã nắm được cơ bản về cấu trúc portlet và thông qua việc phân tích cụ thể 2 file cấu hình ta đã nắm được các thuộc tính tùy chọn quan trọng của một portlet Từ đó ta đã có một hình dung rõ ràng và cụ thể hơn về một portlet
2.1.2 Mô hình MVC trong JSP portlet
Như đã biết, JSP portlet được viết theo mô hình chuẩn của MVCPortlet Framework
- Model (M in MVC): là các file mã java có mục đích chính là quản lý và truy cập dữ liệu Nó được gọi tới bởi các Controller và thực hiện các yêu cầu đó rồi trả kết quả về cho Controller triệu gọi Hiện tại MVCPortlet Framework cung cấp 2 lớp ActionProcessor và RenderProcessor để thực thi mọi hoạt động với cơ sở dữ liệu
- View (V in MVC): Có nhiệm vụ trình bày nội dung trên portal Nó
sử dụng mộ công nghệ phổ biến là JSP Về mặt kĩ thuật, ta có thể
bao gồm cả các dữ liệu đã được trình bay ra dưới mã HTML hoặc
của servlet khác Các trang JSP có thể tận dụng tất cả các hàm có sẵn theo chuẩn của JSP, tuy nhiên nó cũng có thể sử dụng các hàm cung cấp bởi các portlet API Ví dụ như, các tham số yêu cầu không phải thu được từ những đối tượng “request” có sẵn trong trang JSP mà là
từ đối tượng RenderRequest có sẵn hoặc một thư viện API được sử dụng “javax.portlet.renderRequest” hoặc bằng các tab để định nghĩa
“renderRequest”
- Controller (C in MVC): Chứa trong các file mã java có nhiệm vụ xử
lý tất cả các “processAction” và các yêu cầu “render” Trong cả 2
phương pháp, controller cùng xử lý như nhau, và được phân biệt dựa trên một tham số yêu cầu là “request_type” được cung cấp trong lớp
“portlet.mvcportlet.core.RenderProcessor”
2.1.3 Một vài đặc điểm của JSP portlet
- JSP portlet là portlet được sử dụng rộng rãi nhất bởi nó dễ dàng phát triển, mã code dễ hiểu và logic xử lý dễ hình dung
- JSP portlet được sử dụng làm portlet mặc định trong một số IDE phát triển Liferay portal
Trang 15Vaadin là một môi trường phát triển web rất thú vị Ý tưởng chính của Vaadin là lập trình ở phí server, nó cho phép chùng ta không cần để ý nhiều đến các trang web hay giao diện người dùng Trong lập trình web truyền thống, ta có thể sẽ mất nhiều thời gian để đi học tập các công nghệ web mới, các công nghệ truy lỗi với các ngôn ngữ phía client như HTML, Javasctip…trong khi với Vaadin, ta chỉ cần tập trung vào phần xử lý logic của các ứng dụng Với mô hình máy chủ theo định hướng lập trình, Vaadin
sẽ quản lý các giao diện người dùng trong trình duyệt và sử dụng AJAX để làm cầu nối liên lạc giữa trình duyệt và server Thêm vào đó, Vaadin giúp chúng ta tránh được 1 vấn dề khá đau đầu là việc tương thích với trình duyệt
Kiến trúc của VaadinPhần cốt lõi của nó là dựa các thư viện javascript, nó được thiết kế để cho việc tạo, bảo trì một cách dễ dàng các giao diện người dùng trên web Bởi vì HTML, javascript và các công nghệ phía trình duyệt khác là vô hình đối với các ứng dụng logic, vì thế ta có thể coi trình duyệt chỉ như là một client-platform Một client hiển thị giao diện người dùng và giao tiếp với các sự kiện gửi người sử dụng gửi đến server ở mức độ thấp Việc điều khiển logic của giao diện người dùng được chạy như một “Java web server” cùng với các ứng dụng logic khác
Ngược lại, công nghệ client-server bình thường cần phải có rất nhiều ứng dụng khác để liên lạc giữa client và server Vì thế, về cơ bản loại bỏ lớp giao diện người dùng trong kiến trúc phần mềm là một phương pháp tiếp cận rất hiệu quả
Trang 162.2.1 Cấu trúc Vaadin portlet
Hình ảnh cấu trúc Vaadin portlet:
H3 Vaadin portletNhư ta có thể thấy, Vaadin portlet không hề có các file ở phía client ( các file jsp)
Các file portlet.xml, liferay-portlet.xml tương tự như ở portlet
Liferay Có một chút chú ý ở phần <support> Vaadin hỗ trợ chúng ra xem ở 3 mode là view, edit, help
Trang 17<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<! <portlet-mode>edit</portlet-mode> > <! <portlet-mode>help</portlet-mode> >
2.2.2 Hoạt động của Vaadin portlet
Một điểm khác biệt của Vaadin portlet là nó hoàn toàn viết ở phía
server, nên hoạt động của nó cũng có một ít sự khác biệt Có thể hình dung, việc viết Vaadin portlet hoàn toàn giống như việc phát triển các phần mềm dạng winform Người lập trình không cần quan tâm tới các bước « render » ra trinfg duyệt, nó được thực hiện bởi vaadin framework trên server
Vaadin portlet được cấu thành bởi 1 cửa sổ chính (mainWindow), các thành phần khác được coi như các component và được mainWindow quản lý Các component luôn có cơ chế lắng nghe hoạt động, bất kì tương tác nào của người dùng sẽ được thu nhận thông qua các sự kiện và chuyển về server để xử lý
Có thể lấy ví dụ về 1 component Button luôn lắng nghe sự kiện « click »Bất cứ khi nào người dùng « click » vào button đó đều phát sinh một sự kiện là « buttonClick » và được sercer xử lý
Việc hiển thị thông báo ra màn hình như nào ta không cần quan tâm bởi
nó đã được framework qui định
2.2.3 Một vài đặc điểm của Vaadin portlet
Trang 18- Vaadin portlet hoàn toàn được viết từ phía Server: tức là nó chỉ bao gồm các file chứa mã java và cái file xml cấu hình
- Chúng ta không cần quan tâm tới việc sử dụng HTML, CSS hay
javascript
- Vaadin portlet phù hợp với các web mà có yêu cầu cao về xử lý logic
mà không nặng về mặt hình thức
Phần 3: Thực hành – Hướng dẫn phát triển portlet
3 Cài đặt môi trường phát triển portlet
a Các gói cài đặt
Download 3 gói cài đặt chính tại trang chủ của Liferay ( địa chỉ: http://www.liferay.com/ )
- Liferay Portal Community Edition Bundled with Tomcat
(hiện tại đang sử dụng phiên bản 20110225)
liferay-portal-tomcat-6.0.6-(http://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.0.6/liferay-portal-tomcat-6.0.6-20110225.zip/download )
- Eclipse Indigo + Liferay IDE v1.3.1 (Windows 32-bit)
(http://sourceforge.net/projects/lportal/files/Liferay%20IDE/1.3.1/eclipse_Liferay_IDE_1.3.1_v201108302303-win32.zip/
download )
- Plugins SDK (hiện tại đang sử dụng phiên bản 6.0.6-20110225)
liferay-plugins-sdk-(http://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.0.6/liferay-plugins-sdk-6.0.6-20110225.zip/download )
b Cấu hình môi trường
Việc cấu hình bao gồm các bước:
- Install plug-in SDK vào Eclipse: Plugin SDK là một bộ công cụ nhỏ
rất hữu ích được cung cấp bởi Liferay Nó cung cấp nền tảng để phát triển tất cả các bổ sung cho Liferay portal như portlet, theme, hook, template …
Trang 19- Cài đặt môi trường Eclipse IDE: Được xây dựng trên nền tảng của
Eclipse và được tích hợp đầy đủ các tính năng, các thư viện tiện ích của Liferay Eclipse cung cấp môi trường đầy đủ để phát triển các plugin cho Liferay porttal một cách dễ dàng nhất
- Sau khi cài đặt và cấu hình môi trường xong, kích hoạt server Mặc định của Tomcat là chạy localhost tại địa chỉ http://localhost:8080
Nếu các bước cấu hình đúng, một giao diện “Wellcome to
Liferay” sẽ được hiện ra Tài khoản mặc định của hệ thống là
test@liferay.com/test , ta có thể đăng nhập với tài khoản này để
test và thực hiện các chức năng của administrator
H4 Liferay WellcomeChi tiết cách cài đặt và cấu hình được trình bày cụ thể trong phần phụ lục
“Hướng dẫn cài đặt chi tiết”.
3.1 JSP portlet
3.1.1 First-portlet
H5 Demo first-portlet
Trang 20Portlet này là portlet được tạo ra bằng Eclipse, ta chưa hề can thiệp bất cứ j vào phần code Nhìn qua portlet để nhận xét:
- Portlet chỉ có 1 file view.jsp, nội dung đơn giản là câu thông báo “This
is …”
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
This is the <b>FirstProject</b> portlet.
- Nội dung portlet không có gì đáng kể, ta chỉ nhìn qua để biết cấu trúc 1 JSP portlet và chuẩn bị cho bước phát triển tiếp theo
3.1.2 MyGreeting-portlet (simple)
Thay vì chỉ hiển thị một câu thông báo có sẵn “This is …” trong file view.jsp, ta cùng làm một portlet với nhiệm vụ khó hơn, đó là hiển thị ra một lời chào mừng và cho phép người dùng có thể sửa nó:
H6 MyGreeting-portletĐây là phần code đã được sửa trong file view.jsp :
prefix="portlet" %>
%>
<portlet:defineObjects />
Trang 21PortletPreferences prefs =
renderRequest.getPreferences();
String greeting = (String)prefs.getValue(
"greeting", "Hello! Welcome to our portal.");
%>
<p><%= greeting %></p>
<portlet:renderURL var="editGreetingURL">
<portlet:param name="jspPage" value="/edit.jsp"
/>
</portlet:renderURL>
<p><a href="<%= editGreetingURL %>">Edit greeting</a></p>
Và chúng ta tạo thêm một file edit.jsp với nội dung:
prefix="portlet" %>
prefix="aui" %> <%@ page
<portlet:renderURL var="editGreetingURL">
<portlet:param name="jspPage" value="/edit.jsp"
/>
</portlet:renderURL>
<aui:form action="<%= editGreetingURL %>"
method="post">
Trang 22<aui:input label="greeting" name="greeting"
type="text" value="<%= greeting %>" />
<aui:button type="submit" />
</aui:form>
<portlet:renderURL var="viewGreetingURL">
<portlet:param name="jspPage" value="/
view.jsp" />
</portlet:renderURL>
<p><a href="<%= viewGreetingURL %>">Back</a></p>
Để ý sự khác biệt giữa portlet này và portlet đầu tiên:
- Đầu tiên, nó khai báo mội biến String greeting = “Hello Wellcome …”
và cho nó hiển thị ra trinh duyệt
- Sau đó, sử dụng <portlet:renderURL> để link đến trang edit.jsp cho phép sửa đổi nội dung:
< portlet:renderURL var ="editGreetingURL">
< portlet:param name ="jspPage" value ="/edit.jsp" />
</ portlet:renderURL >
< >< a href = <%= editGreetingURL %>"> Edit greeting </ a ></ p
- File edit.jsp có một vài hàm xử lý bao gồm 1 form cho phép người dùng thay đổi nội dung lời chào, và Save nó lại Các thao tác được thực hiện thông qua đối tượng renderRequest và PortletReferences
Ta có thể có 1 vài nhận xét quan trọng về portlet này:
Việc liên kết giữa 2 trang được sử dụng bởi tag
<portlet:renderURL>, nó được định nghĩa trong thư viện
http://java.sun.com/portlet_2_0 Tag này chỉ có duy nhất 1
tham số là tên 1 trang jsp, và nó được MVCPortlet sử dụng để xác định trang web sẽ trả lại kết quả cho mỗi yêu cầu Chúng ta luôn luôn phải định nghĩa taglib <%@ taglib uri="http:// java.sun.com/portlet_2_0" prefix="portlet" %> để có thể sử dụng Hạn chế này tồn tại bởi vì portlet không thật sự là
cả một trang mà chỉ là một phần của trang web, vì thế URL luôn phải chỉ đến đúng portlet mà nó chịu trách nhiệm xử lý Portal sẽ chịu trách nhiệm giải thích tablib với vừa đủ những thông tin mà portlet cần sử dụng
Trong file edit.jsp, có sử dụng tablib AUI đây là một phần của thư viện Alloy UI Alloy UI là một thu viện hỗ trợ giúp đơn giản các
mã code cần thiết cho việc tạo một form
Trang 23Một tab khác được sử dụng là <portlet:defineObjects /
> Việc định nghĩa tab này giúp ta có thể chèn vào jsp một tập hợp các biến ẩn rất hữu ích cho việc phát triển portlet như
renderRequest, portletConfig, portletPreference, …
3.1.3 MyGreeting-portlet1 (Advance)
Trong các ví dụ trên, chúng ta mới chỉ thao tác ở mức View và chưa có j
xử lý ở các mức bên trong, xử lý các file core java
Ở ví dụ này, chúng ta sẽ làm quen với việc đó
Giữ nguyên mà trong file view.jsp, file edit.jsp được thay đổi với nội dung như sau:
String greeting = (String)prefs.getValue(
"greeting", "Hello! Welcome to our portal.");
%>
<portlet:actionURL var="editGreetingURL">
<portlet:param name="jspPage" 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>
Trang 24<portlet:renderURL var="viewGreetingURL">
<portlet:param name="jspPage" value="/view.jsp" /
>
</portlet:renderURL>
<p><a href="<%= viewGreetingURL %>">Back</a></p>
Để ý thì ta có thể thấy, sự khác biệt ở đây nằm ở tag
<portlet:actionURL>, ví dụ trên chúng ta sử dụng <portlet:renderURL>
Trên thực tế, còn 1 tag nữa là <portlet:resourceURL> Sự khác biệt của các tag URL như sau :
- renderURL : đây là loại URL mà chúng ta vẫn dùng, nó dùng để gọi 1 portlet mà chỉ dùng bước render Chúng ta sẽ không can thiệp được vào phần action phase
- actionURL : loại URL này khai báo cho portlet biết cách để thực thi action phase trước khi render portlet vào trong trang
- resourceURL : loại URL này dùng để lấy images, XML, JSON … hay bất khì dạng dữ liệu khác Nó rất tiện ích để tạo các yêu cầu AJAX lên server Điểm khác biệt của loại URL này là ta toàn quyền xử lý dữ liệu gửi phản hồi
Tiếp theo, tạo file MyGreeting.java trong thư mục docroot/WEB-INF/src với nội dung:
ActionRequest actionRequest, ActionResponse actionResponse)
throws IOException, PortletException {
Trang 25PortletPreferences prefs = actionRequest.getPreferences();
String greeting = actionRequest.getParameter("greeting");
if (greeting != null) { prefs.setValue("greeting", greeting);
prefs.store();
}
super.processAction(actionRequest, actionResponse); }
}
Mặc định để xử lý các request từ client thông qua actionURL là processAction,
ở đây chúng ta cần @Override nó để xử lý theo ý muốn
Deloy lại portlet và quan sát kết quả
Nhận xét:
- Sự khác biệt ở đây so với portlet trước là sau khi bấm “Save” nó sẽ
tự động quay trở lại trang view.jsp với lời chào đã được thay đổi –
khác với trường hợp trước ta phải bấm “Back” đê quay lại xem kết
quả Giải thích cho việc này là vì trong ví dụ trước ta chỉ dùng bước render nên chúng ta không can thiệp được vào quá trình xử lý của portal nên cần một thao tác khác để quay lại
- Các ví dụ từ trước đến giờ luôn được thực hiện theo dạng “request - response” Vậy làm thế nào để có thể portal không chỉ chả về các kết quả mà client yêu cầu mà còn chứa cả các thông tin khác nữa? Chúng
ta cần một bước xử lý để có thể truyền biến từ action phase sang render phase Chẳng hạn như một câu thông báo ”Thông tin đã được thay đổi thành công!”
3.1.4 Greeting-Session-Portlet
Như đã trình bày, có 2 cách để truyền biến từ action phase và render phase
và cũng đã có ví dụ để nói rằng cách sử dụng session sẽ có hiệu quả hơn Vì thế trong demo này, chúng ta sẽ sử dụng session để truyền biến từ action tới render phase
Viết lại class Greeting.java và thêm dòng:
Trang 26public void processAction(
ActionRequest actionRequest, ActionResponse actionResponse)
throws IOException, PortletException {
Trang 27String greeting = (String)prefs.getValue(
"greeting", "Hello! Welcome to our portal.");
%>
<p><%= greeting %></p>
<portlet:renderURL var="editGreetingURL">
<portlet:param name="jspPage" value="/edit.jsp" />
</portlet:renderURL>
<p><a href="<%= editGreetingURL %>">Edit</a></p>
Deloy lại portlet, thực hiện thao tác thay đổi lời chào và quan sát kết quả:
3.1.5 Ajax portlet
Trong phần trước, chúng ta đã nhắc đến 3 loại URL, ta đã có 2 ví dụ
tương ứng về renderURL và actionURL, bây giờ chúng ta sẽ sử dụng nốt resourceURL Loại URL này rất thích hợp để thực hiện Ajax vì thế ta sẽ xét
nó qua một ví dụ về Ajax
Trước tiên, chúng ta nói lại một chút về Ajax
Ajax được viết tắt của Asynchronous JavaScript and XML – phương
pháp phía client tạo các request bất đồng bộ - là công nghệ phát triển web dựa trên javascript và XML Đặc điểm của nó là ẩn với người dùng, các ứng dụng web tự tạo các request tới server để lấy dữ liệu mà không cần sự can
Trang 28thiệp của người dùng.
Ajax cho phép tạo ra một Ajax Engine nằm giữa giao giữa client và server Điều này giống như việc tăng thêm một lớp giữa cho ứng dụng để giảm quá trình "đi lại" của thông tin và giảm thời gian phản ứng Khi đó, các yêu cầu gửi resquest và nhận response do Ajax Engine thực hiện Thay vì trả dữ liệu dưới dạng HTML và CSS trực tiếp cho trình duyệt, web server có thể gửi trả
dữ liệu dạng XML và Ajax Engine sẽ tiếp nhận, phân tách và chuyển hóa thành XHTML+CSS cho trình duyệt hiển thị Việc này được thực hiện trên client nên giảm tải rất nhiều cho server, đồng thời người sử dụng cảm thấy kết quả xử lý được hiển thị tức thì mà không cần nạp lại trang Mặt khác, sự kết hợp của các công nghệ web như CSS và XHTML làm cho việc trình bày giao diện trang web tốt hơn nhiều và giảm đáng kể dung lượng trang phải nạp Và thay vì tải lại (refresh) toàn bộ một trang, nó chỉ nạp những thông tin được thay đổi, còn giữ nguyên các phần khác
Chúng ta sẽ có 2 ví dụ về ajax Một sử dụng resourceURL và một sử dụng XMLHTMLRequest
<a href="javascript:;"
onclick="$('#<portlet:namespace/>content').load('<%=currentResUrl.toString() %>');return false;">Sports</a>
Trang 29Phần code trên khai báo một biến thuộc kiểu ResourceURL Biến này
có nhiệm vụ yêu cầu request tới server và nhận giá trị trả về
Một <table> được khai báo chứa link để kích hoạt ajax Chúng ta sẽ gọi ajax qua jQuery Javascript Library API để truyền tải nội
Phía server:
public class changeStatus extends MVCPortlet {
public void serveResource(ResourceRequest
}
}
Chúng ta sẽ phải override hàm serveResouce để nhận các yêu cầu từ phía client để xử lý
Deloy portlet và xem kết quả đạt được
Khi click vào “Sports”
Chúng ta có thể nhận thấy, khi bấm vào link “Sports” thì thông điệp
“It is coding time” được thay đổi thành “It’s sports time” mà các portlet xung quanh không có thay đổi gi Tức là một yêu cầu ajax đã được gửi đến server xử lý và nhận kết quả trả về Các portlet khác không hề bị ảnh hưởng
b XMLHTMLRequest
Trang 30Đây là cách gọi ajax truyền thống, sử dụng một đối tượng
XMLHTTPRequest để gửi yêu cầu tới server và nhận kết quả trả về
<%@page session="false" contentType="text/html"
/* callback function called to check the request
status and retrieve the resposne */