Menu

Sao chép đối tượng (clone) trong Java

Sao chép đối tượng (cloning) là một vấn đề khá quan trọng đối với lập trình viên JAVA. Mới đây thôi, trong dự án của công ty, chúng tôi cũng phải đối mặt với một vấn đề và chúng tôi giải quyết nó bằng việc sử dụng phương thức clone. Post này tôi sẽ lược dịch các nội dung liên quan đến phương thức clone mà tôi cho là thú vị và hữu ích.

Trước hết thì clone là gì? Rất đơn giản: clone là việc tạo ra một đối tượng mới có nội dung giống hết đối tượng được clone.

Liferay 7: Sử dụng Item Selector

Trong phiên bản 7, Liferay đã giới thiệu rất nhiều tính năng mới thú vụ. Một trong số chúng là Item Selector. Nói một cách đơn giản, nó là một thành phần (component) cho phép người dùng chọn nhiều loại tài nguyên khác nhau (ảnh, video, bài viết,...).

Nếu ứng dụng (portlet) của bạn cần phải chọn ảnh/video/bài viết,... từ hệ thống thì Item Selector chính một lựa chọn hợp lý. Item Selector sẽ mở ra một cửa sổ (dialog) lựa chọn cho phép bạn có thể chọn nhiều loại tài nguyên khác nhau như ảnh, video, hoặc bất kỳ dữ liệu nào.

item selector

Liferay 7: Thay đổi giao diện trang quản trị

Trong thực tế, chúng ta thường quan tâm đến giao diện của người dùng cuối (end-user) nhiều hơn so với giao diện quản trị. Chính vì vậy, giao diện quản trị thường không được đầu tư nhiều công sức. Tuy nhiên, tuy từng từ dự án, những người dùng được cấp tài khoản có thể truy cập được trang quản trị (nhân viên, biên tập viên,...). Trong trường hợp này, đương nhiên là chúng ta cần cải thiện giao diện quản trị mặc định để người dùng cảm thấy hứng thú hơn khi sử dụng ứng dụng. Bài viết này sẽ hướng dẫn cách cập nhật giao diện mặc định của Liferay 7.x.

Java 8: Có nên sử dụng filter của Stream API

Java 8 giới thiệu rất nhiều tính năng mới. Trong đó Stream (luồng) cũng là một tính năng cực kỳ hữu ích và được sử dụng thường xuyên (kết hợp với biểu thức Lambda).

Cụ thể Stream là gì? Nó là một đối tượng mới của Java được giới thiệu từ phiên bản Java 8, giúp cho việc thao tác trên danh sách (collection) và mảng (array) trở nên dễ dàng và tối ưu hơn.

Một Stream đại diện cho một chuỗi các phần tử hỗ trợ các hoạt động tổng hợp tuần tự (sequential) và song song (parallel).

Các thao tác của Stream API

Liferay 7.2/DXP: Sử dụng SystemCheckers để theo dõi trạng thái của hệ thống

Liferay 7.2 có nhiều tính năng hay so với các phiên bản trước đó. Bài viết này sẽ giới thiệu một trong số chúng, cụ thể đó là SystemCheckers. Trong các phiên bản cũ, đôi khi hệ thống đã được khởi động xong chúng ta không thấy bất kỳ lỗi gì vì nó không được ghi ra log. Tuy nhiên, chúng ta vẫn không sử dụng được một vài service hoặc module. Ví dụ, một vài service được khai báo (Declarative Service) không thể hoạt động do thiếu tham chiếu đến các service/module khác hoặc bị tham chiếu vòng.

Liferay 7.x: Đăng ký thêm loại dữ liệu vào ElasticSearch

Như chúng ta đã biết, ElasticSearch là công cụ tìm kiếm mặc định trên Liferay 7/DXP. Nó có nhiều tính năng nổi bật hơn so với Lucene trên các phiên bản Liferay cũ. Liferay sử dụng ElasticSearch cho mục đích tìm kiếm nội bộ. Ví dụ: Tìm kiếm full-tẽt, phân tích lưu trữ, auto-complete, kiểm tra chính tả, khoảng cách địa lý... Hiện tại, chung ta có thể sử dụng tất cả các tính năng này cho các Entity mà mình tạo ra bằng cách kế thừa các indexer của ElasticSearch. Bài viết này sẽ chỉ cho bạn cách dụng ElasticSearch cho các entity tự tạo.

Đăng ký thêm loại dữ liệu vào ElasticSearch

Liferay 7.x: Hiểu về Service Tracker

Như chúng ta đã biết, Liferay DXP sử dụng framework OSGi cho môi trường cộng tác giữa các đối tượng (các đối tượng ngày được xem như các services). Khai báo các dịch vụ (Declarative Services (DS) - khái niệm quan trọng của OSGi) là cách để chia sẻ các service giữa các thành phần trong hệ thống. Khi chúng ta khai báo một lớp của Java với annotation @Component thì lớp đó được xem như là một service và sẽ được sử dụng bởi các thành phần khác. Việc sử dụng annotation @Component để biến một lớp của Java thành một service thực sự dễ cài đặt và mở rộng.

Service Tracker

Liferay 7.x: Liên kết đến tài nguyên tĩnh (hình ảnh/js/css) trong portlet

Với Liferay DXP, cách thức phát triển portlet/module có sự thay đổi lớn so với các phiên bản Liferay trước đó. Trước đây, chung ta có để dễ dàng sử dụng các tài nguyên tĩnh như CSS, JS hay các hình ảnh. Các tài nguyên này được xem là một phần của các portlet. Nhưng với Liferay DXP, cách tiếp cận là hoàn toàn khác biệt. Hay xem, làm thế nào để sử dụng được các tài nguyên tĩnh trong việc phát triển portlet/module.

Liferay 7: Error while buildCSS

To day, I open my old wars project and build it with Gradle. I received the error message like this:

Was passed main parameter 'sass.append.css.import.timestamps=true' but no main parameter was defined in your arg class
:wars:announcement:buildCSS

Liferay 7: Service builder và truy vấn dữ liệu

Trong bài viết Liferay 7: Tạo một portlet mới như thế nào?, mình đã hướng dẫn cách tạo một portlet (mvc portlet) trên môi trường Liferay 7. Như bạn thấy, việc tạo mới một portlet trên môi trường Liferay 7 cũng không thực sự khó khăn và mất nhiều thời gian. Tuy nhiên, một ứng dụng không chỉ đơn giản như thế, trong bài viết này mình sẽ đi hướng dẫn cách tương tác với cơ sở dữ liệu (CSDL). Cụ thể là sẽ lấy dữ liệu từ CSDL và hiển thị lên trình duyệt.
Đồng thời, mình cũng đưa ra so sánh cách tổ chức các module, các lớp, interface của phiên bản 7 so với phiên bản 6.x (xem tại đây).

JasperReport: Giới thiệu về JasperReport


JasperReport là một engine tạo báo cáo mã nguồn mở phổ biế nhất hiện tại. Nó được viết hoàn toàn bằng Java và được cho phép sử dụng với nhiều loại nguồn dữ liệu (data source) và tạo ra những báo cáo "chuẩn từng pixcel" cho phép hiển thị, in ấn hoặc xuất ra những định dạng như HTML, PDF, MS Excel, OpenOffice và MS Word.
Hầu hết các ứng dụng trong thực tế cần phải xuất các báo cáo theo nghiệp vụ cũng như theo yêu cầu của khách hàng. Một công cụ tạo báo cáo đơn giản, mạnh mẽ sẽ giúp bạn tiết kiệm được nhiều công sức, thời gian. Vì lý do trên, mình quyết định làm một seri các bài giới thiệu và các tip của bản thân để giới thiệu đến các bạn.

Liferay 7: How to create a new portlet?


There were many interesting features added or improved in Liferay 7. And Liferay Workspace is one of them, it is a new way to organizing our source code and recommended by Liferay. In this post, I will create a portlet by Liferay 7 default style ( it means using Liferay Workspace).
(Phiên bản Tiếng Việt - Vietnamese version)

Liferay 7: Tạo mới một portlet phiên bản 6x

Trong bài viết này, mình đã có giới thiệu cách tạo một portlet theo cách mới của phiên bản Liferay 7.0. Ở đó, mình dùng công cụ Gradle để build project. Nếu để ý một chút, bạn sẽ thấy rằng ở phiên bản 7.0 không thấy sự xuất hiện Liferay SDK. Vậy nếu tạo portlet phiên bản 6x cũ trên môi trường Liferay 7.0 thì như thế nào? Bài viết này sẽ trả lời câu hỏi trên.

Liferay 7: Tạo một portlet mới như thế nào?


English version
Ở bài viết trước, mình đã lược dịch lại những tính năng mà Liferay 7 cải tiến và bổ sung. Trong đó, Liferay Workspace là một tính năng mới, một cách tổ chức code mới được Liferay khuyến khích lập trình viên sử dụng. Trong bài viết này, mình sẽ tạo một portlet theo cấu hình mặc định của Liferay (tức là sử dụng Liferay Workspace), bài viết tiếp theo mình sẽ hướng dẫn cách cấu hình Liferay 7 để bạn có thể tạo ra các portlet theo phong cách cũ (phiên bản Liferay 6).

Java: Tham chiếu và tham trị

Java truyền tham số vào phương thức (hàm) theo kiểu tham số hay tham trị? Một câu hỏi rất dễ tìm câu trả lời trên Google. Và câu trả lời tất nhiên là tham trị! Nhưng vẫn có rất nhiều junior đã, đang nhầm lẫn và cảm thấy nghi ngờ. Bài viết này sẽ đưa ra và ví dụ minh họa để cho ai vẫn đang nhầm lẫn có một cái nhìn rõ hơn.

Liferay 7: Bắt đầu với Liferay 7

Mỗi lần nâng cấp phiên bản, Liferay đều có những cái rất mới mẻ và có thêm những cải tiến hay. Lần này cũng thế, phiên bản 7 với nhiều tính năng mới được trang bị và khác xa với phiên bản 6. Chúng ta hãy cùng đi cài đặt Liferay 7 và xem những tính năng mới của nó dưới con mắt của một developer nhé.

Liferay: Vòng đời của Portlet - Phương thức serveResource()


Portlet có thể gửi các nội dung động từ máy trạm tới máy chủ trong pha phục vụ tài nguyên (serve resource). Chúng ta hãy xem pha này được thực hiện trong Liferay như thế nào nhé.

Liferay: Vòng đời của Portlet - Phương thức processAction()

Pha action (hoạt động) của portlet được thực hiện trong phương thức processAction(). Nó được thực hiện bằng cách gọi một URL action. Người dùng sẽ tương tác với portlet trong pha này.

Liferay 6.2: Vòng đời của Portlet - Phương thức render()

Phương thức vòng đời render chịu trách nhiệm cho việc sinh ra nội dung (được hiển thị trên trình duyệt) của portlet. Nó được gọi khi portlet được thực thi trong pha sinh nội dung.

Liferay 6.2: Vòng đời của Portlet - Phương thức init()

Pha khởi tạo của một portlet được thể hiện bởi phương thức init(). Khi một portlet được triển khai, portlet container sẽ xoá bỏ thể hiện (instance) đã có của nó và tạo các thể hiện mới. Lúc này, phương nó sẽ gọi phương thức init().

Liferay 6.2: Giới thiệu các pha và vòng đời của portlet

Portlet thực hiện một hành động duy nhất trong mỗi chu trình thực thi. Các chu trình này được biết đến là các pha. Mỗi pha/chu trình được thể hiện bởi các phương thức tương ứng trong lớp controller (portlet class).

Liferay 6.2: Cấu hình portlet

Sau khi tạo ra một portlet, bạn hi vọng nó sẽ được sử dụng ở nhiều nơi. Đây thực sự là một hi vọng chính đáng. Tuy nhiên, nếu bạn tạo ra một portlet cứng nhắc sẽ không thể tái sử dụng được. Do vậy, trong quá trình thiết kế portlet, bạn phải đảm bảo rằng portlet của mình thực sự linh hoạt và dễ dàng tùy biến theo từng nhu cầu cụ thể.
Trong bài viết này, mình sẽ hướng dẫn các bạn cách mở rộng cấu hình portlet.

Java: Using POI library to read and write Excel data


Vietnam version
After reading the article title, you can easily guess the intentions of this post, right? Reading and writing excel data are the often actions in our jobs, Therefore, how can you read and write this data by the simplest way? This post is going to answer the above question.

Liferay 6.2: Window popup



Window popup is a utility which was built-in Liferay Framework. Liferay itself also used this utility in many parts. For examples: Window popup appears in permission interface or portlet configurations (if you click on gear icon at top left portlet, the windows will appear which allows changing the configurations).
In general, window popup is useful in the UI design process. So, how to use it. This post will help you

Liferay 6.2: Cửa sổ popup



Cửa sổ popup là một tiện ích được tích hợp sẵn trong Liferay. Bản thân Liferay cũng sử dụng tiện ích này ở nhiều nơi. Ví dụ như trong giao diện phân quyền sử dụng (bạn click vào đường link phân quyền sẽ có một cửa sổ được bật nên để bạn chọn các quyền phù hợp), cấu hình portlet (bạn click vào các đường link cấu hình ở phía trên bên phải của mỗi portlet, sẽ có các cửa sổ được mở lên để bạn thay đổi cấu hình, giao diện, ... của portlet).
Nói chung, cửa sổ popup rất hữu dụng trong quá trình thiết kế giao diện ứng dụng. Vậy, làm thế nào có thể sử dụng được nó. Bài viết này sẽ giúp bạn.

Liferay 6.2: AlloyUI: Node and some familiar methods

AlloyUI (AUI) is an excellent UI framework. It built on top of YUI3 library that uses Bootstrap (HTML/CSS) to provide a simple API for building high scalable applications.
Liferay has integrated AUI into its framework (click here to view detail). So, good understanding and good using AUI are the necessary skills if you want to develop the application on this framework.
In this post, I will show you the most basic component of AUI. That is Node. What is a Node? How does it work? Let's discuss it.

Liferay 6.2: AlloyUI: Node và một số phương thức hay dùng

AlloyUI (AUI) là một công cụ thiết kế giao diện web mạnh mẽ. AUI là một framework được xây dựng dựa trên YUI3 (một thư viện giao diện của Yahoo!) và sử dụng Bootstrap để cung cấp một API đơn giản cho các ứng ụng có khả năng mở rộng cao.
Liferay đã tích hợp sẵn AUI vào trong hệ thống của mình (xem tại đây). Chính vì vậy, việc tìm hiểu và sử dụng tốt AUI là một việc cần thiết khi bạn muốn phát triển các ứng dụng trên framework này.
Trong bài viết này, mình sẽ giới thiệu thành phần cơ bản nhất của AUI. Đó là Node? Vậy Node là gì? Nó hoạt động như thế nào? Hãy cùng thảo luận nhé.

Liferay 6.2: Form validator

validate
Data validation is a necessary work to ensure the smooth of our applications. Fortunately, Liferay Framework has provided a powerful tool for us to do this work. This post will introduce and guide the way to validate data. Let's read it:

Liferay 6.2: Action on multi-rows in Search-Container

Come back with post Liferay: Actions on a row in Search Container, we have added the actions into each result row. However, you can not handle more than two rows at once. So, how do you do if you want to delete multi-row at a moment? Thankfully, Liferay has provided a powerful tool to do this. Let's read this post to get more details.

Liferay 6.2: Xác thực (Validate) dữ liệu

Xác thực (validate) dữ liệu là việc làm cần thiết để đảm bảo ứng dụng của chúng ta vận hành một cách trơn tru nhất. Thật may mắn, Liferay đã cung cấp một công cụ rất hữu ích và mạnh để chúng ta thực hiện công việc này. Bài viết sẽ giới thiệu và hướng dẫn cách thức thực hiện xác thực dữ liệu, cùng đọc nhé:

Liferay 6.2: Actions on a row in Search Container

In two previous posts, I introduced to you how to show the data in table format. Fortunately, Liferay Framework provided the tools to create awesome applications. The applications made by these tools are unification. The unification is one of the factorials which make your applications better.

Liferay 6.2: Reset passwords


Nobody wants to forget the passwords. But it usually happens. It is easy to reset the passwords of normal or lower level users and resetting the password of the administrators is a hard work. So, this post is going to help to reset the password of test@liferay.com (or another administrator account) in this situation.

Liferay 6.2: Using SessionClicks utility


I am sure that you have to use temporary data in building the website, portal. For examples: register the items which are selected in commercial website or memory the status of menus.
There are many methods which help to save that temporary data. In this post, I am going to talk about using SessionClicks utility in JSP and Java code and Liferay.Store in Javascript.

Liferay 6.2: Các vấn đề về thời gian trong Liferay

Bên cạnh các vấn đề về đa ngôn ngữ, các vấn đề về thời gian trong Liferay cũng được quan tâm để có một ứng dụng tuyệt vời. Cũng như các vấn đề về đa ngôn ngữ, bài này sẽ giới thiệu với bạn cách làm thế nào để lưu trữ và hiển thị ngày tháng và thời gian trong Liferay Framework.

Liferay 6.2: Thao tác trên nhiều dòng trong search-container

Trởi lại với bài Liferay: Thao tác trên từng dòng của search-container, chúng ta đã thêm được các thao tác vào từng dòng kết quả. Nhưng nếu muốn xử lý được nhiều hơn một dòng thì phải làm như thế nào? Giả sử, ta muốn xóa một lúc nhiều dòng chẳng hạn thì sẽ xử lý ra sao? Rất may, Liferay cung cấp cho chúng ta một số tiện ích rất thú vị để làm điều này, hãy cùng thảo luận nhé.

Liferay 6.2: Thao tác trên từng dòng của search-container

Trong hai bài viết mà mình đã đăng là: Tìm kiếm & Liệt kê và Kết hợp Search-Container & Cơ sở dữ liệu, mình đã hướng đẫn cách thứ để hiển thị dữ liệu dưới dạng bảng. May mắn thay, Liferay đã cung cấp sẵn cho chúng ta một cách thức để làm việc này nên tạo ra cho chương trình của chúng ta một sự thống nhất nhất định (khi dự án có nhiều người tham gia).

Liferay 6.2: Sử dụng tiện ích SessionClicks

Chắc chắn trong quá trình xây dựng website, cổng thông tin thì bạn phải sử dụng các dữ liệu tạm thời. Mình có thể kể ra các ứng dụng như hiển thị các sản phẩm hoặc mục mà người dùng đã xem, hay sử dụng trong quá trình chọn hàng để mua trong các ứng dụng thương mại điện tử. Hoặc đơn giản là ghi lại trạng thái của thanh thực đơn chẳng hạn.

Liferay 6.2: Đổi mật khẩu admin/test@liferay.com

Quên mật khẩu là việc chẳng ai mong muốn nhưng xảy ra khá thường xuyên. Đối với người dùng bình thường thì có thể thiết lập lại mật khẩu một cách dễ dàng nhưng với tài khoản quản trị thì đó là một lỗi kinh hoàng và ngớ ngẩn nhất. Chính vì vậy, bài này sẽ hướng dẫn một cách thiết lập lại mật khẩu của tài khoản test@liferay.com phòng trường hợp bạn quên.

Một kỹ thuật sử dụng mảng

Trong các ứng dụng thông thường thì rất ít khi sử dụng mảng mà thay vào đó chủ yếu là sử dụng danh sách. Tuy nhiên, trong trường hợp các phần tử là hữu hạn thì dùng mảng là tốt nhất. Trong bài viết này, mình viết là một kỹ thuật sử dụng mảng trong thuật toán đơn giản, sẽ có ích với người mới làm quen với kỹ thuật lập trình.




Liferay 6.2: Custom Dynamic query with array parameters

Liferay Service Builder (LSB) is a great tool for Liferay developers. We use the methods of the services which is generated by LSB in the most of the case. But, you can not work with multi-table. There was a solution in this case (click here to see). This article is a good guide but you cannot execute a query with array parameters. So, executing a custom dynamic query with array parameters is the purpose of this post.

Liferay 6.2: Ví dụ về AJAX trong Liferay

Khỏi phải bàn đến lợi ích của ajax trong trong các ứng dụng web. Với nhiều lợi ích như thế nên ajax được hỗ trợ rất tốt trong Liferay và việc sử dụng nó cũng hết sức đơn giản. Trong bài viết này, mình sẽ làm một ví dụ đơn giản minh họa việc sử dụng ajax giúp cho lập trình viên có thể tạo ra những ứng dụng web độc đáo nhất.

Liferay 6.2: Các vấn đề liên quan đến đa ngôn ngữ trong Liferay

Multi-language
English version
Trong một thế giới rộng lớp, nếu muốn giới thiệu tới tất cả mọi người ứng dụng của mình bạn phải thể hiện nó với nhiều ngôn ngữ khác nhau. May mắn thay, Liferay đã hỗ trợ tính năng này và cung cấp những cách dễ dàng nhất để làm điều đó. Mình sẽ giới thiệu làm thế nào để sử dụng đa ngôn ngữ trong một portlet. Hãy bắt đầu nào.

Liferay 6.2: Hook và tự viết taglib


English version
Hôm nay, mình sẽ thảo luận về việc làm thế nào để viết một jsp taglib. Tại sao cần phải tự viết taglib riêng? Vì các tag này được sử dụng lại trong nhiều dự án khác nhau và các taglib trong các thư viện có sẵn không đáp ứng được nhu cầu của bạn. Ví dụ: tạo một taglib để thể hiện thông tin của một sản phẩm trong các dự án thương mại điện tử hoặc thể hiện thông tin của một quyển sách trong cửa hàng sách online,...
Trong bài này, chúng ta sẽ tạo ra một taglib thể hiện thông tin của một cuốn sách, các thông tin gồm: tiêu đề (title), phiên bản (edition version), số ISBN (ISBN), các tác giả (authors), hình bìa (cover image), tổng số trang (number of pages), nhà xuất bản (publisher),...

Liferay 6.2: Hook and Taglib


Vietnam version
Today, I am going to discuss how to create custom JSP tag-libs. Because custom JSP tags are reused in many projects, creating custom JSP tags is always necessary. For examples: creating a tag-lib to show a product information in e-commerce projects, book information in a bookstore.
In this post, we are going to create a tag-lib which shows the information of a book. The book's information includes title, edition version, ISBN, authors, cover image, the number of pages, publisher,...

SQL: Một trường hợp của lệnh UPDATE trong SQL

Lệnh UPDATE là một lệnh rất hay gặp trong việc thao tác với cơ sở dữ liệu. Cú pháp của lệnh như sau:
UPDATE SET Column_1 = Value_1, ..., Column_n = Value_n [WHERE ....];

Postgresql: Execute some simple commands

Postgresql logo
If you working with small scale database, you always using a database management software to done your task. For example, I usually use pgAdmin to integrated with Postgresql database. In some cases, you have to face with a large-scale database, using a database management isn't best choose. At that moments, I often use commands to done my jobs.
In this post, I will show you how to execute a SQL file from the terminal screen.

Liferay 6.2: Multi-language problems

Multi-language
Vietnam version
In the wide world, if you want to introduce your application, your program have to multi-language. Fortunately, Liferay framework supported this feature and provided easiest ways to do. I will introduce how to using multi-language in a portlet. Let's go.

Java: Sử dụng thư viện POI để đọc và ghi dữ liệu với excel


English version
Ngay khi đọc tiêu đề bài viết, bạn cũng dễ dàng đoán được ý đồ của bài này rồi đúng không? Thao tác nhập và xuất dữ liệu từ file excel là một thao tác rất thường xuyên trong công việc của chúng ta. Vậy, làm thế nào chúng ta có thể nhập và xuất những dữ liệu mà ta mong muốn. Bài này sẽ giúp bạn trả lời câu hỏi trên.

Liferay 6.2: How to use liferay-ui:form-navigator tag

liferay-ui:form-navigator tag is a great graphics component. If your entity has much relative information, liferay-ui:form-navigator tag will be the best choose to show them in a browser. In this post, I will show you how to use liferay-ui:form-navigator tag.

Java: Singleton Pattern và kết nối với cơ sở dữ liệu trong các ứng dụng Java

Singleton pattern
Bài viết này mình sẽ nói đến hai phần i)thứ nhất là Singleton Pattern và ii) thứ hai là kết nối với cơ sở dữ liệu trong các ứng dụng Java đơn giản. Cuối cùng, mình trình bày lý do tại sao mình lại áp dụng Singleton Pattern vào việc kết nối với cơ sở dữ liệu trong các ứng dụng Java.

Liferay: So sánh giữa Liferay MVC va Spring MVC

Liferay MVC vs Spring MVC
So sánh giữa Liferay MVC và Spring MVC là một chủ đề nóng nhất trong cộng động phát triển ứng dụng Liferay. Lập trình viên luôn bối rối khi chọn một trong hai framework này. Trong bài viết này tôi sẽ so sánh giữa hai framework để tạo portlet trong Liferay.
Trước khi thảo luận chi tiết hơn, bạn có thể tham khảo ở các blog sau Liferay MVC PortletSpring MVC Portlet để hiểu các khái niệm cơ bản. Để hiểu được sự giống và khác nhau giữa Liferay MVC và Spring MVC, ta sẽ đi so sánh các đặc trưng giữa hai framework này.