Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

Groovy Web Services

RESTful Web Services

Addressable Resources

GET --> find

POST --> insert

PUT --> update

DELETE --> delete

vs

URL based: "GETful"

params tell the story (rather than path)

Example: Google Chart API

http://chart.apis.google.com/chart?

plus lots of parameters

http://chart.apis.google.com/chart?&cht=bhs&chs=800x360&chd=t:10,15,25,40,65,100,-15,-30,-60,-90,5,10&chm=tInitial+publication,000000,0,0,12|tFavorable+mention+in+GroovyMag,000000,0,1,12|tJolt+award+nomination,000000,0,2,12|tWitty+repartee+on+Letterman,000000,0,3,12|tProduct+placement+in+Harry+Potter+movie,000000,0,4,12|tOprah%27s+Book+Club,000000,0,5,12|tDrunken+rant+on+Larry+King+Live,000000,0,6,12|tBug+found+in+book+source+code,000000,0,7,12|tInformercial+with+ShamWow+guy,000000,0,8,12|tScandalous+YouTube+video%28s%29,000000,0,9,12|tTearful+apology+on+The+View,000000,0,10,12|tO%27Reilly+%27Behind+the+Text%27+Special,000000,0,11,12&chds=-95,140&chtt=Anticipated+Impact+on+%22Making+Java+Groovy%22+Book+Sales&chco=0000ff|0000ff|0000ff|0000ff|0000ff|0000ff|ff0000|ff0000|ff0000|ff0000|0000ff|0000ff

Amazon Product API

Build URL with Groovy

def queryStrng = params.collect { k,v -> "$k=$v" }.join('&')

def url = "${baseUrl}?${queryString}"

Parse XML Results

def response = new XmlSlurper().parse(url)

def item = response.Items.Item

book.title = item.ItemAttributes.Title

Jersey

Annotations for REST

+ WADL

Part of Java EE 6

Grails

"/product/$id"(controller:"product", parseRequest:true){

action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"]

}

import grails.converters.*

class ProductController {

def show = {

if(params.id && Product.exists(params.id)) {

def p = Product.findByName(params.id)

render p as XML

} else {

def all = Product.list()

render all as XML

}

}

}

import grails.converters.*

class BookController {

def books

def list = {

this.books = Book.list()

withFormat {

html bookList:books

js { render "alert('hello')" }

xml { render books as XML }

}

}

}

JAX-WS Web Services

apt

wsimport

Example: ISBN Service

wsimport -keep -p mjg <wsdl_url>

wsgen

Example: Potter's Potions, Ltd.

@WebService

public interface Wizard {

@WebMethod

@WebResult(name="potion")

Potion brewPotion(@WebParam(name="ingredients")

Ingredient[] elements);

@WebMethod

@WebResult(name="when")

Date sendOwl(@WebParam(name="message")

String message);

}

so much for interface / implemenation split

Enter Groovy @Delegate

HTTPBuilder

GroovyWS

Content Negotiation

URL Mappings

Groovy SIB

Groovy @Delegate

Methods forward to delegate

Annoying wsgen Issue

@WebService(endpointInterface="Wizard")

class Granger implements Wizard {

Potion brewPotion(Ingredient[] elements) {

return new Potion(name:'polyjuice',

effect:'change appearance');

}

Date sendOwl(String message) {

return new Date()

}

}

@WebService(endpointInterface="Wizard")

class HogwartsWizard implements Wizard {

@Delegate Wizard wizard

}

Converters

Working from SIB puts SIB class name in WSDL for service and port

Publish Service

RESTful Tools

Wizard wiz = new HogwartsWizard(

wizard:new Granger())

Endpoint.publish('http://.../potions', wiz)

println 'Ready to receive requests...'

Java SIB

JAX-RS (JSR 311)

"Jersey"

Restlets

Grails

Implementations

Potions Client

@WebService(endpointInterface="Wizard")

public class Weasley implements Wizard {

public Potion brewPotion(Ingredient[] elements) {

Potion p = new Potion();

p.setName("veritiserum");

p.setEffect("makes you tell the truth");

return p;

}

public Date sendOwl(String message) {

return new Date();

}

}

wsgen works from SIBs

(Service Implementation Beans)

def url = 'http://chart.apis.google.com/chart?'

def data = ['Initial publication':10,'Favorable mention in GroovyMag':15,

'Jolt award nomination':25,'Witty repartee on Letterman':40,

'Product placement in Harry Potter movie':65,"Oprah's Book Club":100,

'Drunken rant on Larry King Live':-15,'Bug found in book source code':-30,

'Informercial with ShamWow guy':-60,'Scandalous YouTube video(s)':-90,

'Tearful apology on The View':5,"O'Reilly 'Behind the Text' Special":10

]

// For bar chart, format is;

// label,label_color,data_set,point_index,label_size

// Would use a collect here instead, but need an index

def transformed = []

data.keySet().eachWithIndex { val, i ->

transformed << "t${URLEncoder.encode(val,'UTF-8')},000000,0,$i,12"

}

// Blue for positive, red for negative

def colors = data.values().collect() {

(it < 0 ? 'ff0000' : '0000ff')

}.join('|')

def title = 'Anticipated Impact on "Making Java Groovy" Book Sales'

def map = [

'cht' : 'bhs',

'chs' : '800x360',

'chd' : 't:'+ data.values().join(','),

'chm' : transformed.join('|'),

'chds': '-95,140',

'chtt': URLEncoder.encode(title,'UTF-8'),

'chco': colors

]

map.each { key, value ->

url += "&${key}=${value}"

}

println url

Wizard w = new HogwartsWizardService().getHogwartsWizardPort()

def ingredients = []

ingredients << new Ingredient(name:'Sopophorous bean',amount:1)

Potion p = w.brewPotion(ingredients)

println "$p.name: $p.effect"

base?k1=v1&k2=v2...

http://.../product/42

Java SEI

wsgen

Groovy SEI + POJOs

Groovy + POJOs

Looks almost identical

but Java Potions and Ingredients

Groovy SEI

POJO, not POGO

Use @WebMethod

or all public methods exposed

including invokeMethod(), etc

@WebService

interface Wizard {

@WebMethod

@WebResult(name="potion")

Potion brewPotion(@WebParam(name="ingredients")

Ingredient[] elements);

@WebMethod

@WebResult(name="when")

Date sendOwl(@WebParam(name="message")

String message);

}

JAX-WS --> JAXB

--> POGO properties

--> getMetaClass()

--> problems

generates WSDL

(and artifacts)

from bytecodes

POGO

Still Want POGOs?

Use field access rather than properties

@XmlAccessorType(XmlAccessType.FIELD)

class Potion {

String name

String effect

}

Special @XMLAccessor annotation

JAX-WS Tools

wsimport

Groovy Client + JAX-WS Stubs

Parse XML Data

WSDL --> Java

generates Java stubs from WSDL

Holy code generation, Batman

http://webservices.daehosting.com/services/isbnservice.wso?WSDL

Do-It-Yourself WS

Java --> WSDL

def getGame(away,home,year) {

def box = new XmlParser.parse(...)

def awayName = box.@away_fname

...

// add extracted data to a POGO

}

wsimport <options> <wsdl_loc>

Built into Java SE 6

ISBNServiceSOAPType service =

new ISBNService().getISBNServiceSOAP()

boolean ok = service.isValidISBN10("0978739299")

Invoke with Groovy (or Java)

Generate XML with MarkupBuilder

JAX-WS 2.0, including JAXB 2.0

apt

JAX-WS 2.1+ available from Metro

Parse or Slurp XML

annotation processing tool

Ken Kousen

works with Java source only

Baseball Data

No Groovy

Kousen IT, Inc.

ken.kousen@kousenit.com

http://www.kousenit.com

JAX-WS

Online XML game data

http://gd2.mlb.com/components/game/mlb

boxscores for all games on year, month, day

Data in XML format

Making Java Groovy

blog: http://kousenit.wordpress.com

WSDL

twitter: @kenkousen

O'Reilly, 2010 (?)

ISBN 0978739299

Top Down

Server

Skeleton

Client stubs

SIB/SEI

Bottom Up

Generate XML Response

Handlers

Intercept SOAP Messages

builder.games {

games.each { g ->

game(

outcome:"$g.away $g.aScore, ...",

lat:g.stadium.latitude,

lng:g.stadium.longitude

)

}

}

Process using SOAP with Attachments API for Java (SAAJ)

thyme

parsley

rosemary

SAAJ

Related Groovy Projects

Ugly, awkward in Java

Simple, elegant in Groovy

Uses for Handlers

Cross-cutting concerns

Conclusions

(Do-it-yourself AOP)

Logging, security, encryption, routing, etc.

or, app-specific concerns...

  • XML always easier with Groovy
  • Freely intermix with Java
  • JAX-WS tools work with Groovy

GroovyWS

HTTPBuilder

Publish and access web services

Built on Apache HttpClient library

Uses Apache CXF

Automatic parsing based on content type

Uses Groovy builder syntax

Note: both version 0.5

docs are a bit "thin"

caveat emptor

Learn more about creating dynamic, engaging presentations with Prezi