Accessing RESTful Web Services from the JavaFX™ Script ......XML & JSON Parser RSS & Atom...

Preview:

Citation preview

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 Wongakhil@sun.com kinsley.wong@sun.com

Recommended