null

Реализация AJAX с использованием JQuery в MVC-портлетах для Liferay

MVC-портлеты - отличный способ быстро написать несложное приложение для Liferay. В отличие от портлетов на базе JSF или Vaadin, такие приложения удобно создавать с помощью стандартных средств Liferay Plugins SDK и они "весят" существенно меньше. С другой стороны, использование более низкоуровневых фреймворков приводит к большему объёму "рутинной" работы; в частности, все AJAX-скрипты (конечно, если они нужны) программисту нужно писать самостоятельно, что, в связи с особенностями логики обработки запросов, может вызвать определённые трудности.

В этой заметке я рассмотрю решение задачи создания простейшего AJAX-сценария для MVC-портлета. Чтобы не тратить время на реализацию кроссбраузерности нашего скрипта, воспользуемся при его написании известной библиотекой JQuery.

Постановка задачи

Предположим, что у нас есть некий портлет, состоящий из одной JSP-страницы (view) и, собственно, класса портлета. Далее предположим, что по клику по кнопке нам требуется асинхронно вызвать метод someAction(), после чего во всплывающем окне показать сгенерированный этим методом на сервере текст.

Постановка задачи

Последовательность действий

1. Подключаем JQuery к портлету. Для этого её нужно скачать, разместить внутри нашего портлета (например, в каталоге /js) и подключить в конфигурационном файле liferay-portlet.xml с помощью элемента "header-portlet-javascript":

<?xml version="1.0"?>
<!DOCTYPE liferay-portlet-app PUBLIC
 "-//Liferay//DTD Portlet Application 6.0.0//EN"
 "http://www.liferay.com/dtd/liferay-portlet-app_6_0_0.dtd">

<liferay-portlet-app>
	<portlet>
		<portlet-name>com.example.ajax</portlet-name>
		<icon>/icon.png</icon>
		<instanceable>false</instanceable>
		<header-portlet-css>/css/main.css</header-portlet-css>
		<header-portlet-javascript>
			/js/jquery-1.7.1.min.js
		</header-portlet-javascript>
	</portlet>
	...
</liferay-portlet-app>

2. Создаём на нашей странице actionURL, указывающий на наш метод:

<portlet:actionURL name="someMethod" var="someMethodURL"/>

Здесь атрибут "name" указывает на имя метода, а атрибут "var" - на имя переменной, в которой будет храниться URL.

3. Создаём JavaScript-функцию, формирующую AJAX-запрос:

function callSomeMethod(buttonText) {
	jQuery.ajax({
		type : "POST",
		data : "msg=" + buttonText,
		url : "<%= someMethodURL %>",
		success : function(msg) {
			alert('message=' + msg);
		}
	});
}

Эта функция будет передавать некоторый текст (её входной параметр) на сервер по заданному URL методом POST. После получения ответа от сервера будет вызываться функция в блоке "success", которая покажет пользователю всплывающее окно с текстом полученного ответа.

4. Регистрируем событие onClick, чтобы функция вызывалась после клика пользователя по кнопке:

<input type="button" name="message" value="Hello, world!"
	onClick="callSomeMethod(this.value);"/>

5. Пишем код метода в классе портлета:

public static void someMethod(ActionRequest request,
		ActionResponse response) throws Exception {
	// Получаем параметр из запроса
	String message = ParamUtil.getString(request, "msg");

	// Получаем response сервлета
	HttpServletResponse servletResponse = 
		PortalUtil.getHttpServletResponse(response);

	// Открываем поток вывода
	PrintWriter out = servletResponse.getWriter();
	
	// Пишем ответ клиенту
	out.println(message);
		
	// Закрываем поток
	out.flush();
	out.close();
}

Обратите внимание, что для возвращения клиенту произвольного сообщения нам требуется доступ к ответу сервлета, а не портлета. При этом, инкапсулирующий его объект получается не из объекта javax.portlet.ActionResponse, а через API com.liferay.portal.util.PortalUtil.

Теперь можно собрать наш портлет, запустить его и убедиться, что всё работает:

Работающий портлет

Коротко о себе:

Работаю ведущим программистом в компании Tune IT и ассистентом кафедры Вычислительной техники в Университете ИТМО .

Занимаюсь проектами, связанными с разработкой разного рода веб-приложений (порталы, CRM-системы, системы электронного документооборота), а также, в рамках научной работы на кафедре, изучаю возможности применения семантического анализа в задачах САПР.