Portlet事件也是JSR-286(Portlet 2.0新添加的一种Portlet之间交互的方式),比起Public Render参数的交互方式,它可以传递大对象而不只局限于字符串或者字符串数组,而且可以启用cache.比起PortletSession,它又支持跨Portlet应用的Portlet交互.

(我惊叹:果然事件驱动的思想深入人心并且无处不在啊,已经在无数地方看到了事件驱动的强大能力了)

 

步骤1:先定义一个Event类,它必须实现Serializable接口, 因为有可能要被远程的Portlet容器里面的Portlet所接受,所以要在网络传输因此要被序列化,序列化的方式就是用JAXB将其转为XML文档然后在网络上传输。

这个@XmlRootElement表示这个事件将以xml的形式被Portlet容器发布出去

  1. import chapter11.code.listing.domain.Book; 
  2. import javax.xml.bind.annotation.XmlRootElement; 
  3. @XmlRootElement 
  4. public class BookAddedEvent implements Serializable
  5. private static final long serialVersionUID = ... 
  6. private String name; 
  7. private String author; 
  8. private Long isbnNumber; 
  9. private String category; 
  10. public BookAddedEvent() { 
  11. //-- do nothing 
  12. public BookAddedEvent(Book book) { 
  13. this.name = book.getName(); 
  14. this.author = book.getAuthor(); 
  15. this.category = book.getCategory(); 
  16. this.isbnNumber = book.getIsbnNumber(); 
  17. ... 

然后这个Book添加的事件就会转为如下的XML序列化的文档并且在网络上传输:

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
  2. <bookAddedEvent> 
  3. <author>Ramnivas Laddad</author> 
  4. <category>Java</category> 
  5. <isbnNumber>1933988053</isbnNumber> 
  6. <name>AspectJ in Action, Second Edition</name> 
  7. </bookAddedEvent> 

 

步骤2:在发送者Portlet的方法中添加这个事件对象:

  1. public class BookCatalogPortlet extends GenericPortlet { 
  2. @ProcessAction(name = "addBookAction"
  3. public void addBook(...)... { 
  4. ... 
  5. Book book = new Book(category, name, author, Long 
  6. .valueOf(isbnNumber)); 
  7. //调用bookService的addBook方法来添加这本书
  8. bookService.addBook(book); 
  9. //同时,创建一个QualifiedName来代表事件的唯一名称(有了某个名字空间)
  10. QName eventName = new QName( 
  11. "http://www.mynamespace.com""bookAddedEvent" 
  12. ); 
  13. //在response对象中,将Event的内容和Event的QName进行绑定
  14. response.setEvent(eventName, new BookAddedEvent(book); 
  15. ... 

 

步骤3:在portlet.xml的<portlet>中声明这个portlet所支持的发布事件,并且在portlet应用级别显式的定义它所发布的事件<supported-publishing-event>(事件的qname关联到具体的事件类类型)

  1. <portlet-app...> 
  2. <portlet> 
  3. <portlet-name>bookCatalog</portlet-name> 
  4. <portlet-class> 
  5. chapter11.code.listing.base.BookCatalogPortlet 
  6. </portlet-class> 
  7. ... 
  8. <supported-publishing-event> 
  9. <qname xmlns:n="http://www.mynamespace.com"> 
  10. n:bookAddedEvent</qname> 
  11. </supported-publishing-event> 
  12. </portlet> 
  13. <event-definition> 
  14. <qname xmlns:n="http://www.mynamespace.com"> 
  15. n:bookAddedEvent</qname> 
  16. <value-type>chapter11.code.listing.base. 
  17. BookAddedEvent</value-type> 
  18. </event-definition> 
  19. ... 
  20. </portlet-app> 

 

步骤4;在接收者Portlet中,用代码显示的从事件中获取所需要的内容并且处理:

 

  1. public class RecentlyAddedBookPortlet extends GenericPortlet ... 
  2.  
  3. @ProcessEvent(qname= 
  4.  
  5. "{http://www.mynamespace.com}bookAddedEvent"
  6.  
  7. public void processAddedBookEvent(EventRequest 
  8.  
  9. request, EventResponse eventResponse) throws...{ 
  10.  
  11. Event event = request.getEvent(); 
  12.  
  13. BookAddedEvent bookAddedEvent = 
  14.  
  15. (BookAddedEvent)event.getValue(); 
  16.  
  17. eventResponse.setRenderParameter("category"
  18.  
  19. bookAddedEvent.getCategory()); 
  20.  
  21. eventResponse.setRenderParameter("name"
  22.  
  23. bookAddedEvent.getName()); 
  24.  
  25. eventResponse.setRenderParameter("author"
  26.  
  27. bookAddedEvent.getAuthor()); 
  28.  
  29. eventResponse.setRenderParameter("isbnNumber"
  30.  
  31. String.valueOf(bookAddedEvent.getIsbnNumber())); 
  32.  
  33.  
 
步骤5:在接收者Portlet的portlet.xml中定义这个Portlet所能处理的事件<supported-processing-event>:
 
  1. <portlet-app...> 
  2. <portlet> 
  3. <portlet-name>recentBook</portlet-name> 
  4. <portlet-class> 
  5. chapter11.code.listing.base.RecentlyAddedBookPortlet 
  6. </portlet-class> 
  7. ... 
  8.  
  9. <supported-processing-event> 
  10. <qname xmlns:n="http://www.mynamespace.com"> 
  11. n:bookAddedEvent</qname> 
  12. </supported-processing-event> 
  13. </portlet> 
  14. <event-definition> 
  15. <qname xmlns:n="http://www.mynamespace.com"> 
  16. n:bookAddedEvent</qname> 
  17. <value-type>chapter11.code.listing.base. 
  18. BookAddedEvent</value-type> 
  19. </event-definition> 
  20. ... 
  21. </portlet-app>