Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
book-of-vaadin.pdf
Скачиваний:
88
Добавлен:
24.03.2015
Размер:
13.43 Mб
Скачать

Portal Integration

Efficiency

Sending data through the browser requires loading and sending it in HTTP requests. The data is held in the memory space of the browser, and handling large data in the client-side JavaScript code can take time. Noticeably large message data can therefore reduce the responsiveness of the application and could, in extreme cases, go over browser limits for memory consumption or JavaScript execution time.

12.9.4. Communication Through Session Attributes

In many cases, such as when considering security or efficiency, it is better to pass the bulk data on the server-side and use the client-side IPC only for notifying the other portlet(s) that the data is available. Session attributes are a conveninent way of sharing data on the server-side. You can also share objects through them, not just strings.

The session variables have a scope, which should be APPLICATION_SCOPE. The "application" refers to the scope of the Java web application (WAR) that contains the portlets.

If the communicating portlets are in the same Java web application (WAR), no special configuration is needed. You can also communicate between portlets in different WARs, in which case you need to disable the private-session-attributes parameter in liferay-portlet.xml by setting it to false. Please see Liferay documentation for more information regarding the configuration.

You can also share Java objects between the portlets in the same WAR, not just strings. If the portlets are in different WARs, they normally have different class loaders, which could cause incompatibilities, so you can only communicate with strings and any object data needs to be serialized.

Session attributes are accessible through the PortletSession object, which you can access through the portlet context from the Vaadin Application class.

Person person = new Person(firstname, lastname, age);

...

PortletSession session = ((PortletApplicationContext2)getContext()).

getPortletSession();

// Share the object

String key = "IPCDEMO_person"; session.setAttribute(key, person,

PortletSession.APPLICATION_SCOPE);

// Notify that it's available liferayipc.sendEvent("ipc_demodata_available", key);

You can then receive the attribute in a LiferayIPCEventListener as follows:

public void eventReceived(LiferayIPCEvent event) { String key = event.getData();

PortletSession session = ((PortletApplicationContext2)getContext()).

getPortletSession();

// Get the object reference

Person person = (Person) session.getAttribute(key);

// We can now use the object in our application

338

Communication Through Session Attributes

Portal Integration

BeanItem<Person> item = new BeanItem<Person> (person); form.setItemDataSource(item);

}

Notice that changes to a shared object bound to a user interface component are not updated automatically if it is changed in another portlet. The issue is the same as with double-binding in general.

12.9.5. Serializing and Encoding Data

The IPC events support transmitting only plain strings, so if you have object or other non-string data, you need to format or serialize it to a string representation. For example, the demo application formats the trivial data model as a semicolon-separated list as follows:

private void sendPersonViaClient(String firstName,

String lastName, int age) { liferayIPC_1.sendEvent("newPerson", firstName + ";" +

lastName + ";" + age);

}

You can use standard Java serialization for any classes that implement the Serializable interface. The transmitted data may not include any control characters, so you also need to encode the string, for example by using Base64 encoding.

//Some serializable object MyBean mybean = new MyBean();

...

//Serialize

ByteArrayOutputStream baostr = new ByteArrayOutputStream(); ObjectOutputStream oostr;

try {

oostr = new ObjectOutputStream(baostr); oostr.writeObject(mybean); // Serialize the object oostr.close();

} catch (IOException e) { Notification.show("IO PAN!"); // Complain

}

// Encode

BASE64Encoder encoder = new BASE64Encoder();

String encoded = encoder.encode(baostr.toByteArray());

// Send the IPC event to other portlet(s) liferayipc.sendEvent("mybeanforyou", encoded);

You can then deserialize such a message at the receiving end as follows:

public void eventReceived(LiferayIPCEvent event) { String encoded = event.getData();

// Decode and deserialize it

BASE64Decoder decoder = new BASE64Decoder(); try {

byte[] data = decoder.decodeBuffer(encoded); ObjectInputStream ois =

new ObjectInputStream(

new ByteArrayInputStream(data));

// The deserialized bean

MyBean deserialized = (MyBean) ois.readObject(); ois.close();

... do something with the bean ...

Serializing and Encoding Data

339

Portal Integration

}catch (IOException e) { e.printStackTrace(); // Handle somehow

}catch (ClassNotFoundException e) {

e.printStackTrace(); // Handle somehow

}

}

12.9.6. Communicating with Non-Vaadin Portlets

You can use the Vaadin IPC for Liferay to communicate also between a Vaadin application and other portlets, such as JSP portlets. The add-on passes the events as regular Liferay JavaScript events. The demo WAR includes two JSP portlets that demonstrate the communication.

When sending events from non-Vaadin portlet, fire the event using the JavaScript Liferay.fire() method with an event ID and message. For example, in JSP you could have:

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:defineObjects />

<script>

function send_message() { Liferay.fire('hello', "Hello, I'm here!");

}

</script>

<input type="button" value="Send message" onclick="send_message()" />

You can receive events using a Liferay JavaScript event handler. You define the handler with the on() method in the Liferay object. It takes the event ID and a callback function as its parameters. Again in JSP you could have:

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:defineObjects />

<script>

Liferay.on('hello', function(event, data) { alert("Hello: " + data);

});

</script>

340

Communicating with Non-Vaadin Portlets

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]