accessing restful web services from the javafx™ script ......xml & json parser rss & atom...
TRANSCRIPT
Accessing RESTful Web Services from the JavaFX™ Script Platform
Akhil Arora & Kinsley WongSun Microsystems, Inc.
2
Agenda
Asynchronous HTTPXML & JSON ParserRSS & Atom API
3
Introduction
All APIs are in the Common profile● identical API for desktop, mobile, TV
This presentation is based on APIs in JavaFX SDK version 1.2
4
Agenda
Asynchronous HTTPjavafx.io.http
XML & JSON ParserRSS & Atom API
5
HttpRequest
Asynchronous HTTP client API with progress indicators and callbacksdef http = HttpRequest { location:“http://javafx.com” method:HttpRequest.GET}http.start()
6
HttpRequest: Progress Indicators
State Transitions (false → true)► started► connecting // status = “connecting...”► doneConnect► writing // status = “writing data...” (if POST or PUT)► doneWrite► readingHeaders► doneHeaders // if (responseCode != HttpStatus.OK) ...► reading // status = “reading data...”► doneRead► done
7
HttpRequest: Progress Callbacks
State Transitions via callbacksonConnecting:function() { status = “connecting...” }onWriting:function() { status = “writing data...” }onReading:function() { status = “reading data...” }onResponseCode:function(code:Integer) { if (code != HttpStatus.OK) { status = “failed:{request.responseMessage}” }}
8
HttpRequest: Read Progress
Using bind► toread:Long // -1 if content-length header is not set► read:Long // updated as bytes are readif (toread > 0) percent = (read * 100) / toread
Using callbacksvar max;onToRead:function(bytes:Long) { max = bytes }onRead:function(bytes:Long) { if (max > 0) percent = (bytes * 100) / max}
9
HttpRequest: Write Progress
Using bind► towrite:Long // -1 if not available► written:Long // updated as bytes are writtenif (towrite > 0) percent = (written * 100) / towrite
Using callbacksvar max;onToWrite:function(bytes:Long) { max = bytes }onWritten:function(bytes:Long) { if (max > 0) percent = (bytes * 100) / max}
10
HttpRequest: Reading Data
Using bind► input:java.io.InputStream
Using callbackonInput:function(is:java.io.InputStream):Void { try { println(“{is.available()} bytes available”) } finally { is.close() }}
> data is cached, so reader will not block> must close stream after use
11
HttpRequest: Writing Data
Using bind► output:java.io.OutputStream
Using callbackonOutput:function(os:java.io.OutputStream):Void { try { os.write(“my data”.getBytes()) } finally { os.close() } }
> writes are cached, so writer does not block> must close stream after use, which also initiates
the actual sending of data over the network
12
HttpRequest: Bulk Data Read
For downloading large data, typically mediaSpecify a destination for data and start as usual
► sink:java.io.OutputStreamdef bos = new java.io.ByteArrayOutputStream()def http = HttpRequest { location:“http://javafx.com” sink: bos}http.start()
when done, bos should contain the contents of javafx.com
13
HttpRequest: Bulk Data Write
For uploading large data, typically mediaSpecify a source of data and start as usual
► source:java.io.InputStreamdef is = ... // image or video streamdef http = HttpRequest { location:“http://cloud.sun.com/uploads” method:HttpRequest.POST headers:[HttpHeader.basicAuth(user,password)] source:is}http.start()
when done, the contents of is should be available at the upload location specified
14
HttpRequest: Setting Request Headers
Set the headers var to set HTTP request headers► headers:HttpHeader[]headers: [ HttpHeader { name:HttpHeader.CONTENT_TYPE value:”image/jpeg” }, // convenience function for creating an HTTP Basic Auth header HttpHeader.basicAuth(username, password)]
15
HttpRequest: Get Response Headers
Get all header names and values► responseHeaders:HttpHeader[]
Using callback► onResponseHeaders:function(headerNames: String[])
Get specific header by name► getResponseHeaderNames():String[]► getResponseHeaderValue(name:String):String
Exampledef etag = getResponseHeaderValue(HttpHeader.ETAG)
16
URL Encoding and Decoding
Encoding and Decoding of URL ParametersCan customize delimiters and specify options
► encodeAsterisk► encodeSpaceAsPercent
def params = [ Pair{name:”symbol” value:”JAVA”}, Pair{name:”from” value:”oct, 1 2008”}, Pair{name:”to” value:”nov, 1 2008”} ]def converter = URLConverter {}def url = “http://quoteservice.com?” converter.encodeParameters(params);// assert url == “http://quoteservice.com?symbol=JAVA&from=oct%2C+1+2008&to=nov%2C+1+2008
17
Agenda
Asynchronous HTTPXML & JSON Parser
javafx.data.pulljavafx.data.xml
RSS & Atom API
18
PullParser
Mobile-friendly - does not build a Document Object Model in memory
Generates a sequence of Events as it processes the document
Works in pull mode, but can also emulate pushCan jump forward to elements of interestIdentical API for XML and JSON
19
Levels (or Depth)<Result> <Rating> <AverageRating>4.5</AverageRating> </Rating> <Distance>2.67</Distance></Result>"Result":[ {"Rating": {"AverageRating":"4.5"}, "Distance":"2.67" }}
Result is at level 0Rating, Distance are at level 1
AverageRating is at level 2
20
Parser Events and LevelsSTART_DOCUMENTSTART_ELEMENT 0 “Result” START_ELEMENT 1 “City” TEXT 1 “Palo Alto” END_ELEMENT 1 “City” START_ELEMENT 1 “State” TEXT 1 “CA” END_ELEMENT 1 “State”END_ELEMENT 0 “Result”END_DOCUMENT
<Result> <City>Palo Alto</City> <State>CA</State></Result>
21
PullParser
The PullParser class► documentType: PullParser.XML► input: ... // a java.io.InputStream that contains XML► encoding: “utf-16” ► ignoreWhiteSpace: true► event:Event► onEvent:function(event:Event):Void
documentType can be JSON or XML (default)encoding defaults to utf-8ignoreWhiteSpace defaults to false
22
Parser Events
The Event class► type:Integer► typeName:String► level:Integer► qname:QName // XML► name:String // JSON► getNamespacePrefixes():String[]► getNamespace(prefix:String)► getAttributeNames():QName[]► getAttributeValue(name):String
23
Seeking Happiness
Problem: what is the value of happiness?<world> <self> <happiness>... is a state of mind.</happiness> </self></world>
24
Looking for Happiness
Problem: what is the value of happiness?<world> <self> <happiness>... is a state of mind.</happiness> </self></world>
Strategy 1: look for happinesswhile (parser.event.type != PullParser.TEXT and parser.event.qname.name != “happiness” and parser.event.level != 2) { parser.forward() }def happiness = parser.event.text// assert happiness == “... is a state of mind.”
25
Emulating Push
Strategy 2: wait for happiness to be sent your wayvar happiness:String;PullParser { input: ... onEvent: function(event:Event) { if (event.type == PullParser.TEXT and event.qname.name == “happiness” and event.level == 2) { happiness = event.text } }}.parse();// assert happiness == “... is a state of mind.”
26
Seeking Happiness
Strategy 3: seek happinessparser.seek(“happiness”, 2); // now at START_ELEMENTparser.forward(); // now at TEXTdef happiness = parser.event.text// assert happiness == “... is a state of mind.”
Or simplydef happiness = parser.seek(“happiness”, 2).forward().event.text// assert happiness == “... is a state of mind.”
27
JSON EventsSTART_DOCUMENTSTART_ELEMENT 0 START_VALUE “number” INTEGEREND_VALUE “number”START_VALUE “array” START_ARRAY START_ARRAY_ELEMENT TRUE END_ARRAY_ELEMENT END_ARRAYEND_VALUE “array”END_ELEMENT 0END_DOCUMENT
{ “number”:123, “array”:[true]}
28
Agenda
Asynchronous HTTPXML & JSON ParserRSS & Atom API
javafx.data.feedjavafx.data.feed.atomjavafx.data.feed.rss
29
Feed API
Mobile-friendly, streaming APIEach Entry or Item is delivered incrementally as
it is parsed● Atom: Feed followed by zero or more Entries● RSS: Channel followed by zero or more Items
30
FeedTask
The FeedTask abstract classBase class for Atom and RSS Tasks
► location:String // feed URL► interval:Duration // poll interval► onException:function(ex:java.lang.Exception)► onForeignEvent:function(event:Event)
the onForeignEvent callback reports events that are not in the native namespace
31
AtomTask
class AtomTask extends FeedTask► onFeed:function(feed:Feed)► onEntry:function(entry:Entry)
ExampleAtomTask { location:”http://blogs.sun.com/.../atom” interval:2h onFeed:function(feed:Feed) { title = feed.title.text } onEntry:function(entry:Entry) { show(entry) }}.start()
32
RssTask
class RssTask extends FeedTask► onChannel:function(channel:Channel)► onItem:function(item:Item)
ExampleRssTask { location:”http://developers.sun.com/rss/javafx.xml” interval:1h onChannel:function(channel:Channel) { title = channel.title } onItem:function(item:Item) { show(item) }}.start()
33
Summary
This presentation covered how to use the webservices APIs in JavaFX version 1.2 to
> fetch resources from the network over HTTP using the asynchronous HTTP client library
> extract information of interest from XML and JSON
> subscribe to RSS and Atom feeds and extract information from them to use in your own applications
34
Resources
Learnhttp://javafx.com/learn
Samples that use JavaFX WebServices APIshttp://javafx.com/samples/InterestingPhotos/index.htmlhttp://javafx.com/samples/LocalSearch/index.htmlhttp://javafx.com/samples/ShoppingService/index.htmlhttp://javafx.com/samples/RSSViewer/index.html
Akhil Arora & Kinsley [email protected] [email protected]