xpages binary output

34
Vi tales ved Vi tales ved iZone iZone XPages Binary Output The only limitation is your imagination John Foldager, izone.dk DanNotes November 28th 2013

Upload: johnfoldager

Post on 20-Jun-2015

1.060 views

Category:

Technology


2 download

Tags:

DESCRIPTION

XPages Binary Output - The only limitation is your imagination John Foldager, izone.dk DanNotes November 28th 2013

TRANSCRIPT

Page 1: XPages Binary Output

Vi tales vedVi tales ved

iZoneiZone

XPages Binary OutputThe only limitation is your imagination

John Foldager, izone.dkDanNotes November 28th 2013

Page 2: XPages Binary Output

iZoneiZone

About John Foldager● Born in 1974 and have been working with IT – especially

programming since the age of 7 – at iZone since 1999

● Member of Notesnet.dk – association of approx. 25 independent consultants

● Vice chairman of Eclipse.dk

● Mentor at Egedal CoderDojo

● Pro Cross-platform development (IBM i, Linux, Unix, BSD, Windows, Solaris, AIX, Raspberry Pi, Android, …)

● Pro Java/OSGi (scalability, deployment, extensibility, …)

● Pro HTML5/CSS3/JavaScript

● Follow me on Twitter @JohnFoldager

Page 3: XPages Binary Output

iZoneiZone

Introduction● Normal use of XPages uses HTML, Dojo, IBM OneUI etc.

● Sometimes other formats/content are needed

● Text output● XML (eXtensible Markup Language), JSON (JavaScript Object Notation), CSV

(Comma Separated Values), SVG (Scalable Vector Graphics), …

● Binary output● Media: images (PNG, JPEG, GIF, …), video (MPEG, …), sound (MP3, Ogg, …)● Document formats: PDF (Portable Document Format), OpenXPS (Open XML

Paper Specification), ODF (Open Document Format), OOXML (Office Open XML), …

● Other: SVG (Scalable Vector Graphics), Archives (ZIP, …), …

● We will show how to...

● use XPages, XAgents, NSF servlets and OSGi servlets

● embed and/or download content

Page 4: XPages Binary Output

iZoneiZone

XAgents● Who uses XAgents [in the audience]?

● First mentioned by Stefan Wissel on http://www.wissel.net/blog/d6plinks/shwl-7mgfbn

● XAgents are XPages where property rendered is set to false and some code is put into beforeRenderResponse (binary) or afterRenderResponse (text)

● Code is SSJS (Server Side JavaScript)● Easy and quick to write because you are on the same 'page'

● Evaluated at runtime (lower performance)

● Harder to debug and unit test

● Some examples...

Page 5: XPages Binary Output

iZoneiZone

XAgents – XML example● Create an XPage where property rendered is set to false

and put the following code in the afterRenderResponse (SSJS)

● var external = facesContext.getExternalContext();var writer = facesContext.getResponseWriter();var response = external.getResponse();

response.setContentType("text/xml");response.setHeader("Cache-Control", "no-cache");

writer.write("<?xml version='1.0' encoding='utf-8'?>\r\n");writer.write("<say>Hello World!</say>");

writer.endDocument();facesContext.responseComplete();

Page 6: XPages Binary Output

iZoneiZone

XAgents – JSON example● Create an XPage where property rendered is set to false

and put the following code in the afterRenderResponse (SSJS)

● var external = facesContext.getExternalContext();var writer = facesContext.getResponseWriter();var response = external.getResponse();

response.setContentType("application/json");response.setHeader("Cache-Control", "no-cache");

writer.write("{\r\n");writer.write(" 'say':'Hello World!'\r\n");writer.write("}\r\n");

writer.endDocument();facesContext.responseComplete();

Page 7: XPages Binary Output

iZoneiZone

XPages – Other formats● Who [in the audience] have tried to deliver non-standard HTML

from an XPage (without using XAgents) and having 100% control of all content?

● First mentioned by John Foldager on http://xpages.dk/?p=83

● XPages can be set to create non-HTML content very easily● NOTE: Several guides on the Internet describes various ways of removing Dojo,

OneUI etc. – but none of them gives you absolutely full control of the entire content. For the most part you overrule everything for all XPages inside the NSF, even though you might only want to do so for a single XPage.

● Only thing you need to do is set the rendererType to javax.faces.Text and set createForm to false

● Some examples...

Page 8: XPages Binary Output

iZoneiZone

XPages – Custom output (1)● Create a Hello World XPage

Page 9: XPages Binary Output

iZoneiZone

XPages – Custom output (2)● Change DOCTYPE to HTML5 compliant (globally inside NSF)

Page 10: XPages Binary Output

iZoneiZone

XPages – Custom output (2)● Change DOCTYPE to HTML5 compliant (globally inside NSF)

Page 11: XPages Binary Output

iZoneiZone

XPages – Custom output (3)● Expand includes (globally inside NSF)

Page 12: XPages Binary Output

iZoneiZone

XPages – Custom output (4)● Remove Dojo (globally inside NSF)

Page 13: XPages Binary Output

iZoneiZone

XPages – Custom output (5)● Remove form and fields (locally to current XPage)

Page 14: XPages Binary Output

iZoneiZone

XPages – Custom output (6)● Remove the rest (locally to current XPage)

Page 15: XPages Binary Output

iZoneiZone

XPages – Custom output (7)● Your own HTML5 content (locally to current XPage)

Page 16: XPages Binary Output

iZoneiZone

XPages – HTML5 example● Create an XPage with the following source

● <?xml version="1.0" encoding="UTF-8"?><xp:view xmlns:xp="http://www.ibm.com/xsp/core" createForm="false" rendererType="javax.faces.Text">

<xp:this.afterRenderResponse><![CDATA[#{javascript:var external = facesContext.getExternalContext();var response = external.getResponse();response.setContentType("text/html");response.setHeader("Cache-Control", "no-cache");response.setHeader("Pragma", "no-store");}]]></xp:this.afterRenderResponse>

<xp:text escape="false" disableTheme="true"><xp:this.value><![CDATA[#{javascript:'<!DOCTYPE html>\n'}]]></xp:this.value></xp:text>

<html lang="en"><head> <content encoding="utf-8"/> <title>My HTML5 page</title></head><body> <header><h1>My HTML5 page delivered from an XPage</h1></header></body>

</xp:view>

Page 17: XPages Binary Output

iZoneiZone

XPages – XML example #1● Create an XPage with the following source

● <?xml version="1.0" encoding="UTF-8"?><xp:view xmlns:xp="http://www.ibm.com/xsp/core" createForm="false" rendererType="javax.faces.Text">

<xp:this.afterRenderResponse><![CDATA[#{javascript:var external = facesContext.getExternalContext();var response = external.getResponse();response.setContentType("text/xml");response.setHeader("Cache-Control", "no-cache");response.setHeader("Pragma", "no-store");}]]></xp:this.afterRenderResponse>

<xp:text escape="false" disableTheme="true"><xp:this.value><![CDATA[#{javascript:'<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n'}]]></xp:this.value></xp:text>

<say>Hello World!</say>

</xp:view>

Page 18: XPages Binary Output

iZoneiZone

XPages – XML example #2● Create an XPage with the following source

● <?xml version="1.0" encoding="UTF-8"?><xp:view xmlns:xp="http://www.ibm.com/xsp/core" createForm="false" rendererType="javax.faces.Text">

<xp:this.afterRenderResponse><![CDATA[#{javascript:var external = facesContext.getExternalContext();var response = external.getResponse();response.setContentType("text/xml");response.setHeader("Cache-Control", "no-cache");response.setHeader("Pragma", "no-store");}]]></xp:this.afterRenderResponse>

<xp:text escape="false" disableTheme="true"><xp:this.value><![CDATA[#{javascript:'<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n'}]]></xp:this.value></xp:text>

<xp:repeat id="repeat" rows="30" var="dataentry" removeRepeat="true"> <xp:this.facets> <xp:text disableTheme="true" xp:key="header" escape="false"> <xp:this.value><![CDATA[<customers>]]></xp:this.value> </xp:text> <xp:text disableTheme="true" xp:key="footer" escape="false"> <xp:this.value><![CDATA[</customers>]]></xp:this.value> </xp:text> </xp:this.facets>

<xp:this.value><![CDATA[#{javascript:[1,2,3,4]}]]></xp:this.value>

<xp:text escape="false" disableTheme="true"> <xp:this.value><![CDATA[#{javascript:"<customer>" + dataentry + "</customer>\n"}]]></xp:this.value> </xp:text></xp:repeat>

</xp:view>

Page 19: XPages Binary Output

iZoneiZone

What did we learn so far?● Now we know how to create our own content from an XPage

(disabling all defaults) and from an XAgent (XPage)

● So what exactly did we learn?● We learned how to overrule whatever XPage engine is normally generating

● We learned how to use XPages repeat-control and Data Source

● We learned how to set the Content Type

● We learned how to set headers (fx. Caching)

● We basically learned that XPages can be used for sooooooo much more than what we normally use it for

Page 20: XPages Binary Output

iZoneiZone

Download?● How can we make the browser download the content?

● This is actually pretty easy. We just need to add another HTTP Header to the response

● <?xml version="1.0" encoding="UTF-8"?><xp:view xmlns:xp="http://www.ibm.com/xsp/core" createForm="false" rendererType="javax.faces.Text">

<xp:this.afterRenderResponse><![CDATA[#{javascript:var external = facesContext.getExternalContext();var response = external.getResponse();response.setContentType("text/plain");response.setHeader("Cache-Control", "no-cache");response.setHeader("Pragma", "no-store");response.setHeader("Content-Disposition", "attachment; filename=MyFilename.txt");}]]></xp:this.afterRenderResponse>

Hello World!

</xp:view>

Page 21: XPages Binary Output

iZoneiZone

Even more control?● So can we get even more control?

● YES!

● We can use servlets either from inside the NSF or using an OSGi bundle, but before we get to that...

● We will try to create a Java class that can be called from a button or link on a normal XPage to download some content

● An example...

Page 22: XPages Binary Output

iZoneiZone

Download from XPage (1)● Steps to follow

● Create a Java Managed Bean class to deliver content

● Create entry for bean in faces-config.xml

● Create button or link on XPage to call bean

Remember Per Henrik Lausten's presentation earlier today?

Page 23: XPages Binary Output

iZoneiZone

Download from XPage (2)● Steps to follow

● Create a Java Managed Bean class to deliver content● package dk.izone.demos.download;

import java.io.IOException;import java.io.OutputStream;import java.io.Serializable;import javax.faces.context.ExternalContext;import javax.faces.context.FacesContext;import com.ibm.xsp.webapp.XspHttpServletResponse;import dk.izone.demos.utils.io.FileIO;

public class DownloadBean implements Serializable { private static final long serialVersionUID = 1L; public DownloadBean() {}

public void download() { try { byte[] file = FileIO.readFile("C:\\temp\\MyArchive.zip"); FacesContext context = FacesContext.getCurrentInstance(); ExternalContext external = context.getExternalContext(); XspHttpServletResponse response = (XspHttpServletResponse) external.getResponse(); response.setContentType("application/zip"); response.setHeader("Content-Disposition", "attachment; filename=MyArchive.zip"); response.setHeader("Content-Length", String.valueOf(file.length)); OutputStream os = response.getOutputStream(); os.write(file); os.close(); context.responseComplete(); } catch (IOException e) { e.printStackTrace(); } }

}

Page 24: XPages Binary Output

iZoneiZone

Download from XPage (3)● Steps to follow

● Create a Java Managed Bean class to deliver content

● Create entry for bean in faces-config.xml● <?xml version="1.0" encoding="UTF-8"?>

<faces-config>

<managed-bean> <managed-bean-name>MyBean</managed-bean-name> <managed-bean-class>dk.izone.demos.download.DownloadBean</managed-bean-class> <managed-bean-scope>application</managed-bean-scope> </managed-bean>

</faces-config>

Page 25: XPages Binary Output

iZoneiZone

Download from XPage (4)● Steps to follow

● Create a Java Managed Bean class to deliver content

● Create entry for bean in faces-config.xml

● Create button or link on XPage to call bean● <xp:button id="button1" value="Download">

<xp:eventHandler event="onclick" submit="true" refreshMode="complete"> <xp:this.action><![CDATA[#{javascript:MyBean.download();}]]></xp:this.action> </xp:eventHandler></xp:button>

● <xp:link id="link1" text="Download"> <xp:eventHandler event="onclick" submit="true" refreshMode="complete"> <xp:this.action><![CDATA[#{javascript:MyBean.download();}]]></xp:this.action> </xp:eventHandler></xp:link>

Page 26: XPages Binary Output

iZoneiZone

Acknowledgement● The previous example is a rewrite of an example by Jakob

Majkilde which can be found on http://xpages.dk/?p=1396

Page 27: XPages Binary Output

iZoneiZone

Standard Java? #1● Can we get even more control and use standard Java?

● YES!

● We can use Java Servlets either from inside the NSF or using an OSGi bundle. We will start by showing the NSF way...

● We will show a Java Servlet that

● will reside inside the NSF so that it can be deployed like we “use to”

● looks “a little bit” like a real standard Java Servlet

● core Java developers should be able to work from template

● An example...

Page 28: XPages Binary Output

iZoneiZone

Standard Java? #1● Depend on Extension Library

● Create Java class that extends DefaultServletFactory

● Create file META-INF/services/com.ibm.xsp.adapter.servletFactory and put Java class package and name in

● An example...

Page 29: XPages Binary Output

iZoneiZone

Standard Java? #2● Can we create standard Java Servlets using Eclipse IDE (or

any other IDE based on Eclipse) and deploy to the Domino server as an OSGi bundle?

● YES! We can even do it using an Update Site :-)

● We can create servlets to either an Equinox HTTP Service or Expeditor Web Container (J2EE)

● We will show a Java servlet that

● is an Eclipse OSGi plugin project

● is a real standard Java Servlet

● core Java developers should be able to work right away

● An example...

Page 30: XPages Binary Output

iZoneiZone

Standard Java? #2● An example...

Page 31: XPages Binary Output

iZoneiZone

3rd Party Java API Deployment● There are plenty of Java APIs that can be downloaded on the

Internet and used for various purposes

● Examples● Apache Software Foundation (apache.org)

● Images

● Barcodes (Barcode4J, …)

● Office Files (Apache POI, ODF Toolkit, OOXML, …)

● PDFs (Apache PDF Box, iText, …)

● etc.

● So lets see how we can deploy these 3rd party Java APIs using OSGi bundles

Page 32: XPages Binary Output

iZoneiZone

Need Help?● You are more than welcome to contact “Gang of Four”

● Jakob Majkilde, majkilde.dk

● Per Henrik Lausten, phl-consult.dk

● John Dalsgaard, dalsgaard-data.dk

● John Foldager, izone.dk

Page 33: XPages Binary Output

iZoneiZone

Links● Here are some links that refer to related information

● DOCTYPE – http://www.dominoguru.com/pages/change_xpage_doctype.html

● Domino OSGi development – http://www.slideshare.net/fiorep/domino-osgi-development

Page 34: XPages Binary Output

iZoneiZone

Questions? Contact!● You are more than welcome to contact me directly

● Website: http://izone.dk

● Phone: +45 20 22 22 11

● Email: [email protected]

● LinkedIn: http://dk.linkedin.com/in/foldager

● Twitter: @JohnFoldager

● Google+: +JohnFoldager

● http://john.foldager.tel