Native REST Web Services with Oracle 11g

45
Native REST Web Services with Oracle 11g CLOUG 2009 Marcelo F. Ochoa - Fac. Cs. Exactas - UNICEN - Tandil - Arg.

description

Chile Oracle User Group 2009

Transcript of Native REST Web Services with Oracle 11g

Page 1: Native REST Web Services with Oracle 11g

Native REST Web Services with Oracle 11g

CLOUG 2009

Marcelo F. Ochoa - Fac. Cs. Exactas - UNICEN - Tandil - Arg.

Page 2: Native REST Web Services with Oracle 11g

AgendaRESTRestlet framework XDB Restlet adapterXDB Restlet adapter architectureMy first REST application

Performance test Comparison against SOAP

Data Service Architecture and SOA last mileData Service example

DataServiceApplicationUserResourceOrdersResourceOrderResource

Page 3: Native REST Web Services with Oracle 11g

What is REST?

REpresentational State TransferFormalized by Roy Fielding in his PhD DissertationPrimarily applicable to distributed hypermedia systemsThink of it as resource-orientation

Resources represent the domain concepts Championed by the Web community

Amazon, Yahoo, Google Adopted by some of the major vendors (Microsoft:WCF, Sun:Jersey)Positioned as an alternative to WS-* implementationsHigh impact in the community (Ruby on Rails, RESTlet)

Page 4: Native REST Web Services with Oracle 11g

Motivation for REST

Take advantage of what the Web does wellSimplicityScalabilityPerformanceEase of use

So much nicer than the alternativesSOAP & WS - *

Unifies Web Sites and Web Services into consistent Web Applications

Page 5: Native REST Web Services with Oracle 11g

A Style, Not a Standard

REST guides the use of standardsExamples:

HTTP (Connector)URI (Resource)XML, HTML, GIF, etc. (Representations)text/xml, text/html, image/gif, etc. (Media types)

The Web is a REST system

Page 6: Native REST Web Services with Oracle 11g

REST Architectural Style

Composition of styles that gains their benefits:Client-Server - separation of concerns, scalabilityLayered – allows intermediaries (proxies, firewalls) without affecting interfacesStateless – scalabilityCacheable – reduces payload & latencyPipe-and-Filter – dynamic component connection

Page 7: Native REST Web Services with Oracle 11g

REST at glanceCartoon by Eric Lemerdy (http://eric.lemerdy.free.fr)

ResourcesA Resource should be a fixed target of a URIThe URI-to-Resource mapping shouldn't change, but the representation can Resources may map to multiple representations, called variants

Example: png, gif, jpg are variantrepresentations of an imageContent negotiation selects the best variant

Uniform interfaceResources are manipulated by HTTPmethods

GET – retrieve a resourcePUT – create a resourcePOST – update (create if necessary) a resourceDELETE – delete a resource

CacheabilityA cache can return copy in response to a GET, therefore prefer GET over POST

Page 8: Native REST Web Services with Oracle 11g

What is Restlet?

An open source REST framework for JavaA good mapping of REST principlesFounded by Jérôme Louvel,Noelios Consulting, Paris, France http://www.restlet.org/Built in response to:

Need for a simple, RESTful web application frameworkServlet limitations

Page 9: Native REST Web Services with Oracle 11g

Restlet Framework

Restlet API – Supports REST call handlingExtensions – For integrating external technologies (JDBC,JSON, alternate containers, connectors, template engines, etc.)SPI – Plugin point for alternate implementationsRestlet Implementation – Currently just Noelios Engine

Application

Restlet API

SPI XDB

Restlet Implementation

Extensions

Page 10: Native REST Web Services with Oracle 11g

Restlet framework

Page 11: Native REST Web Services with Oracle 11g

Representations

Page 12: Native REST Web Services with Oracle 11g

XDB AdapterXdbServerServlet extends ServerServletA Servlet 2.2 compliant connectorXdbServletCall extends HttpServerCallA Servlet 2.2 version of ServletCall classXdbServletConverter extends HttpServerConverterConverter of low-level HTTP server calls into high-level uniform callsXdbServletWarClient extends ClientConnector acting as a WAR client for a Servlet Application. Support XMLDB repository browsingXdbServletWarClientHelper extends ServletWarClientHelperLocal client connector based on a XMLDB repository. Translate:URL: file:///$HOME/myPath/myFile.ext -> XDB: /home/SCOTT/myPath/myFile.ext

URL: war:///myPath/myFile.ext -> XDB: /home/SCOTT/wars/HelloRestlet/myPath/myFile.ext

Servlet running with PUBLIC grants run with an effective user ANONYMOUS

Page 13: Native REST Web Services with Oracle 11g

XDB Servlet adapter architecture

HTTP presentation over TCP/IP is used to support native REST WS

Page 14: Native REST Web Services with Oracle 11g

XDB Adapter application stack

Client alternatives:an AJAX application (GWT , DOJO Toolkit)a RIA application (Flex, Lazlo, etc.)a middle tier consuming REST WS (REST client stack)

Client side:ApplicationContext's client dispatcherHTTP client connectorHTTP protocolTCP layerIP layer

Server side:ResourceRouterServices (decompression,range, tunnel, etc.)HTTP server connector (XDB)HTTP protocol TCP layerIP layer

Page 15: Native REST Web Services with Oracle 11g

Installing XDB Restlet Adapter

Using Reslet SVN 1.2M4 (SQLNet string test )# cd reslet/build# ant# cd dist/classic/restlet-1.2snapshot/src/org.restlet.ext.xdb/resources/# cat ~/build.propertiessqlnet.string=testjdbc.username=RESTLETjdbc.password=RESTLETjdbc.sysusr=sysjdbc.syspwd=change_on_install# ant allBuildfile: build.xmlcreate-schema:.....BUILD SUCCESSFULTotal time: 1 minute 58 seconds

Page 16: Native REST Web Services with Oracle 11g

My first REST application

Extracted from Restlet tutorial 12 (automatically installed)package org.restlet.example.tutorial ; public class Part12 extends Application {

@Override public Restlet createRoot() { // Create a router final Router router = new Router(getContext());

// Attach the resources to the router router.attach("/users/{user }", UserResource .class); router.attach("/users/{user }/orders", OrdersResource .class); router.attach("/users/{user }/orders/{order }", OrderResource .class);

// Return the root router return router; }}

Page 17: Native REST Web Services with Oracle 11g

ResourcesUserResource

public class UserResource extends Resource { String userName;

Object user;

public UserResource(Context context, Request request, Response response) { super(context, request, response); this.userName = (String) request.getAttributes().get("user "); this.user = null; // Could be a lookup to a domain object.

// Here we add the representation variants exposed getVariants().add(new Variant(MediaType.TEXT_PLAIN)); }

@Override public Representation represent(Variant variant) throws ResourceException { Representation result = null; if (variant.getMediaType().equals(MediaType.TEXT_PLAIN)) { result = new StringRepresentation("Account of user \"" + this.userName + "\""); } return result; }}

Page 18: Native REST Web Services with Oracle 11g

Resources - cont.OrdersResource

public class OrdersResource extends UserResource {

public OrdersResource(Context context, Request request, Response response) { super(context, request, response); }

@Override public Representation represent(Variant variant) throws ResourceException { Representation result = null;

if (variant.getMediaType().equals(MediaType.TEXT_PLAIN)) { result = new StringRepresentation("Orders of user \"" + this.userName + "\""); }

return result; }

}

Page 19: Native REST Web Services with Oracle 11g

Resources - cont.OrderResource

public class OrderResource extends UserResource { String orderId;

Object order;

public OrderResource(Context context, Request request, Response response) { super(context, request, response); this.orderId = (String) request.getAttributes().get("order "); this.order = null; // Could be a lookup to a domain object. }

@Override public Representation represent(Variant variant) throws ResourceException { Representation result = null;

if (variant.getMediaType().equals(MediaType.TEXT_PLAIN)) { result = new StringRepresentation("Order \"" + this.orderId + "\" for user \"" + this.userName + "\""); } return result; }}

Page 20: Native REST Web Services with Oracle 11g

Loading demos

Already done during installation step#ant load-server-side-demos Buildfile: build.xml

load-server-side-demos: [java] arguments: '-nodefiner' '-r' '-v' '-s' '-g' 'public' '-u' 'RESTLET/***@test ' '../../../lib/org.restlet.example.jar' ..... [exec] SQL> Disconnected from Oracle Database 11g Release 11.1.0.6.0 - Production

BUILD SUCCESSFULTotal time: 14 seconds

Page 21: Native REST Web Services with Oracle 11g

Registering a REST Applicationrem http://localhost:8080/userapp/users/scott/orders/300DECLARE configxml SYS.XMLType;begin dbms_xdb.deleteServletMapping('UsersRestlet'); dbms_xdb.deleteServlet('UsersRestlet'); dbms_xdb.addServlet(name=>'UsersRestlet',language=>'Java', class=>'org.restlet.ext.xdb.XdbServerServlet ', dispname=>'Restlet Servlet',schema=>'PUBLIC'); SELECT INSERTCHILDXML(xdburitype('/xdbconfig.xml ').getXML(),'/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/servlet-list/servlet[servlet-name="UsersRestlet"]','init-param', XMLType('<init-param xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"> <param-name>org.restlet.application</param-name> <param-value>RESTLET :org.restlet.example.tutorial.Part12 </param-value> <description>REST User Application</description> </init-param>'),'xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"') INTO configxml FROM DUAL; dbms_xdb.cfg_update(configxml); dbms_xdb.addServletSecRole(SERVNAME => 'UsersRestlet', ROLENAME => 'PUBLIC',ROLELINK => 'PUBLIC'); dbms_xdb.addServletMapping('/userapp/ *','UsersRestlet'); commit;end;

Page 22: Native REST Web Services with Oracle 11g

Testing your REST application

Test using command line (telnet) # telnet localhost 8080Trying 127.0.0.1...Connected to mochoa (127.0.0.1).Escape character is '^]'.GET /userapp/users/scott/orders/300 HTTP/1.0Host: localhost:8080

HTTP/1.1 200 OKMS-Author-Via: DAVDAV: 1,2,<http://www.oracle.com/xdb/webdav/props>Date: Thu, 02 Apr 2009 21:52:45 GMTServer: Noelios-Restlet-Engine/1.2snapshotAccept-Ranges: bytesContent-Type: text/plain; charset=ISO-8859-1Vary: Accept-Charset, Accept-Encoding, Accept-Language, AcceptContent-Length: 28

Order "300" for user "scott"

Page 23: Native REST Web Services with Oracle 11g

Benchmarking REST applications

Page 24: Native REST Web Services with Oracle 11g

Adding caching behavior

Add an expiration time now plus 10 seconds@Overridepublic Representation represent(Variant variant) throws ResourceException {Representation result = null;

if (variant.getMediaType().equals(MediaType.TEXT_PLAIN)) {result = new StringRepresentation("Order \"" + this.orderId

+ "\" for user \"" + this.userName + "\"");}Date expirationDate = new Date(System.currentTimeMillis()+10000);result.setExpirationDate(expirationDate); return result;}

Page 25: Native REST Web Services with Oracle 11g

Benchmarking caching behavior

Page 26: Native REST Web Services with Oracle 11g

Comparing against a SOAP applicationExample application

create or replace and compile java source named "my.OrderCalculator" aspackage my;import java.util.logging.Level;import java.util.logging.Logger;public class OrderCalculator { /** * Java Util Logging variables and default values */ private static Logger logger = null; /** * Constant used to get Logger name */ static final String CLASS_NAME = OrderCalculator.class.getName(); static { logger = Logger.getLogger(CLASS_NAME); logger.setLevel(Level.ALL); } public static String getOrder(String userName, int orderId) { logger.entering(CLASS_NAME,"getOrder",new Object [] {userName,new Integer(orderId)}); logger.exiting(CLASS_NAME,"getOrder","Order '"+orderId+"' for user '"+userName+"'"); return "Order '"+orderId+"' for user '"+userName+"'"; }}

Page 27: Native REST Web Services with Oracle 11g

Defining a Call Spec

PLSQL Call Spec to provide execution as stored procedureCREATE OR REPLACE PACKAGE orders_calculator AUTHID CURRENT_USER AS FUNCTION getOrder(user_name IN VARCHAR2, order_id IN NUMBER) RETURN VARCHAR2 as LANGUAGE JAVA NAME 'my.OrderCalculator.getOrder(java.lang.String, int) return java.lang.String';END orders_calculator;

POST message to call above procedure with SOAP sintax <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://xmlns.oracle.com/orawsv/SCOTT/ORDERS_CALCULATOR/GETORDER"> <env:Header/> <env:Body> <ns1:SVARCHAR2-GETORDERInput> <ns1:USER_NAME-VARCHAR2-IN>scott</ns1:USER_NAME-VARCHAR2-IN> <ns1:ORDER_ID-NUMBER-IN>300</ns1:ORDER_ID-NUMBER-IN> </ns1:SVARCHAR2-GETORDERInput> </env:Body></env:Envelope>

Page 28: Native REST Web Services with Oracle 11g

SOAP performance

Page 29: Native REST Web Services with Oracle 11g

Current SOA landscape

Source: http://soa.sys-con.com/node/620374

Page 30: Native REST Web Services with Oracle 11g

Data Services technology

Source: http://soa.sys-con.com/node/620374

Page 31: Native REST Web Services with Oracle 11g

Data Service example

Key technologies usedXDB Restlet adapterXMLDB repository as persistent layerJava in the databaseXdbRepresentationOracle AQ for faster insertXQuery

Think Data Services as data abstraction layer, not as simple CRUD services

Page 32: Native REST Web Services with Oracle 11g

Data Service Application

public class DataServiceApplication extends Application { @Override public Restlet createRoot() { // Create a router final Router router = new Router(getContext());

// Attach the resources to the router router.attach("/users/{user}", UserResource.class); router.attach("/users/{user}/orders", OrdersResource.class); router.attach("/users/{user}/orders/{order}", OrderResource.class);

// Return the root router return router; }}

Page 33: Native REST Web Services with Oracle 11g

Data Service Application UserResourcepublic class UserResource extends Resource {... public UserResource(Context context, Request request, Response response) { super(context, request, response); this.userName = (String)request.getAttributes().get("user");.. try {.. preparedstatement = this.conn.prepareStatement("select XMLElement(\"User\"," + "XMLAttributes(? as \"UserName\",? as \"UserID\",SYSDATE as \"Created\"))" + " from dual");... if (resultset.next()) { user = resultset.getObject(1);.. setAvailable(false); }... } finally { XdbServerServlet.closeDbResources(preparedstatement, resultset); } // Here we add the representation variants exposed getVariants().add(new Variant(MediaType.TEXT_XML)); }}

Page 34: Native REST Web Services with Oracle 11g

UserResource - GET public Representation represent(Variant variant) throws ResourceException { Representation result = null; if (variant.getMediaType().equals(MediaType.TEXT_XML)) { if (user instanceof XMLType) result = new XdbRepresentation(variant.getMediaType(), (XMLType)this.user); else generateErrorRepresentation("Returned object is not XMLType", "", this.getResponse()); } Date expirationDate = new Date(System.currentTimeMillis()+10000); result.setExpirationDate(expirationDate); return result; } Sample Output GET /ds/users/sbell HTTP/1.0Authorization: Basic c2NvdHQ6dGlnZXI=Host: localhost:8080

HTTP/1.1 200 OKMS-Author-Via: DAVDAV: 1,2,<http://www.oracle.com/xdb/webdav/props>Date: Sat, 04 Apr 2009 17:59:59 GMTServer: Noelios-Restlet-Engine/1.2snapshotAccept-Ranges: bytesContent-Type: text/xmlVary: Accept-Charset, Accept-Encoding, Accept-Language, AcceptExpires: Sat, 04 Apr 2009 18:00:09 GMT

<User UserName="sbell" UserID="SBELL" Created="2009-04-04"></User>

Page 35: Native REST Web Services with Oracle 11g

UserResource - POST handler public void acceptRepresentation(Representation entity) { int i = 0; XMLType order; PreparedStatement preparedstatement = null; try { order = XMLType.createXML(this.conn, entity.getStream());

preparedstatement = this.conn.prepareStatement(enqueueStmt); preparedstatement.setObject(1, order); preparedstatement.setString(2,schUrl); i = preparedstatement.executeUpdate(); this.conn.commit(); String orderId = order.extract("/PurchaseOrder/Reference/text()", null).getStringVal();

getResponse().setStatus(Status.SUCCESS_CREATED); getResponse().setLocationRef(getRequest().getResourceRef() + "/" + orderId.substring(this.userName.length()+1)); getResponse().setEntity(order.getStringVal(), MediaType.TEXT_XML); } catch (SQLException sqe) {... } Enqueue operation: enqueueStmt = " dbms_aq.enqueue(queue_name => 'PO$Q',\n" + ... " payload => message.createSchemaBasedXML(?),\n" + ... "end;\n";

Page 36: Native REST Web Services with Oracle 11g

UserResource - Sample POSTPOST /ds/users/sbell/orders HTTP/1.0Host: localhost:8080Authorization: Basic c2NvdHQ6dGlnZXI=Content-Type: text/xml; charset=ISO8859_1Content-Length: 844

<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:8080/home/SCOTT/poSource/xsd/purchaseOrder.xsd"> <Reference>SBELL-20030409123336231PDT</Reference> <Actions> <Action> <User>SVOLLMAN</User> </Action> </Actions> <Reject/> <Requestor>Sarah J. Bell</Requestor> <User>SBELL</User> <CostCenter>S30</CostCenter> <ShippingInstructions> <name>Sarah J. Bell</name> <address>400 Oracle Parkway......</address> <telephone>650 506 7400</telephone> </ShippingInstructions> <SpecialInstructions>COD</SpecialInstructions> <LineItems> <LineItem ItemNumber="1"> <Description>Juliet of the Spirits</Description> <Part Id="37429165829" UnitPrice="29.95" Quantity="2"/> </LineItem> </LineItems></PurchaseOrder>

Page 37: Native REST Web Services with Oracle 11g

OrdersResoure public class OrdersResource extends UserResource { public OrdersResource(Context context, Request request, Response response) { super(context, request, response); ResultSet resultset = null; PreparedStatement preparedstatement = null; try { // Gets a list of Orders for given User preparedstatement = this.conn.prepareStatement("SELECT XMLQuery('<Orders>\n" + " {for $i in ora:view(\"PURCHASEORDER\")/PurchaseOrder\n" + " where $i/User = $userid\n" + " return\n" + " <PurchaseOrder>\n" + " {$i/Reference}\n" + " </PurchaseOrder>\n" + " }\n" + " </Orders>' PASSING ? as \"userid\"\n" + " RETURNING CONTENT) AS orders FROM DUAL"); preparedstatement.setString(1, this.userName.toUpperCase()); resultset = preparedstatement.executeQuery();

if (resultset.next()) { orders = resultset.getObject(1);... } finally { XdbServerServlet.closeDbResources(preparedstatement, resultset); } }

Page 38: Native REST Web Services with Oracle 11g

OrdersResource - Represent public Representation represent(Variant variant) throws ResourceException { Representation result = null; if (variant.getMediaType().equals(MediaType.TEXT_XML)) { if (this.orders instanceof XMLType) result = new XdbRepresentation(variant.getMediaType(), (XMLType)this.orders); else generateErrorRepresentation("Returned object is not XMLType", "", this.getResponse()); } return result; }Sample OutputGET /ds/users/sbell/orders HTTP/1.0Authorization: Basic c2NvdHQ6dGlnZXI=Host: localhost:8080

HTTP/1.1 200 OKMS-Author-Via: DAVDAV: 1,2,<http://www.oracle.com/xdb/webdav/props>Date: Sat, 04 Apr 2009 18:17:09 GMTServer: Noelios-Restlet-Engine/1.2snapshotAccept-Ranges: bytesContent-Type: text/xmlVary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

<Orders><PurchaseOrder><Reference>SBELL-20030409123336231PDT</Reference><Requestor>Sarah J. Bell</Requestor><CostCenter>S30</CostCenter></PurchaseOrder></Orders>

Page 39: Native REST Web Services with Oracle 11g

OrderResourcepublic class OrderResource extends UserResource { public OrderResource(Context context, Request request, Response response) { super(context, request, response); this.orderId = (String)request.getAttributes().get("order");.. try { // Gets a list of Orders for given User preparedstatement = this.conn.prepareStatement(selectStmt); preparedstatement.setString(1, this.userName.toUpperCase() + "-" + this.orderId); resultset = preparedstatement.executeQuery();

if (resultset.next()) { order = resultset.getObject(1);... } else { setModifiable(true); setAvailable(false); } } catch (SQLException sqe) {.. } finally { XdbServerServlet.closeDbResources(preparedstatement, resultset); } } selectStmt: public static final String selectStmt = "select * from " + table + " where existsNode(object_value," + "'/PurchaseOrder[Reference=\"'||?||'\"]')=1";

Page 40: Native REST Web Services with Oracle 11g

OrderResource - DELETE handler public void removeRepresentations() throws ResourceException { int i = 0; if (this.order != null) { // Remove the item from the list. PreparedStatement preparedstatement = null; try { // Gets a list of Orders for given User preparedstatement = this.conn.prepareStatement(deleteStmt); preparedstatement.setString(1, this.userName.toUpperCase() + "-" + this.orderId); i = preparedstatement.executeUpdate(); this.conn.commit(); // Tells the client that the request has been successfully fulfilled. getResponse().setStatus(Status.SUCCESS_MULTI_STATUS); getResponse().setEntity("Deleted " + i + " record(s).", MediaType.TEXT_PLAIN);

} catch (SQLException sqe) {... } finally { XdbServerServlet.closeDbResources(preparedstatement, null); }... } } deleteStmt: public static final String deleteStmt = "delete from " + table + " where existsNode(object_value," + "'/PurchaseOrder[Reference=\"'||?||'\"]')=1";

Page 41: Native REST Web Services with Oracle 11g

OrderResource - DELETE - sampleDELETE /ds/users/sbell/orders/20030409123336231PDT HTTP/1.0Authorization: Basic c2NvdHQ6dGlnZXI=Host: localhost:8080

HTTP/1.1 207 Unknown errorMS-Author-Via: DAVDAV: 1,2,<http://www.oracle.com/xdb/webdav/props>Date: Sat, 04 Apr 2009 22:54:09 GMTServer: Noelios-Restlet-Engine/1.2snapshotAccept-Ranges: bytesContent-Type: text/plain; charset=ISO-8859-1Content-Length: 20

Deleted 1 record(s).

Page 42: Native REST Web Services with Oracle 11g

OrderResource - PUT handler public void storeRepresentation(Representation entity) throws ResourceException { int i = 0; PreparedStatement preparedstatement = null; boolean newOrder = (this.order == null); try { this.order = XMLType.createXML(this.conn, entity.getStream()); if (newOrder) { preparedstatement = this.conn.prepareStatement(enqueueStmt); preparedstatement.setObject(1, this.order); preparedstatement.setString(2,schUrl); } else { preparedstatement = this.conn.prepareStatement(updateStmt); preparedstatement.setObject(1, this.order); preparedstatement.setString(2, this.userName.toUpperCase() + "-" + this.orderId); } i = preparedstatement.executeUpdate(); this.conn.commit();... } finally { XdbServerServlet.closeDbResources(preparedstatement, null); } } updateStmt: public static final String updateStmt = "update " + table + " set object_value = ?" + " where existsNode(object_value," + "'/PurchaseOrder[Reference=\"'||?||'\"]')=1";

Page 43: Native REST Web Services with Oracle 11g

OrderResource - PUT - samplePUT /ds/users/sbell/order/20030409123336231PDT HTTP/1.0 Host: localhost:8080Authorization: Basic c2NvdHQ6dGlnZXI=Content-Type: text/xml; charset=ISO8859_1Content-Length: 1005

<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:8080/home/SCOTT/poSource/xsd/purchaseOrder.xsd"> <Reference>SBELL20030409123336231PDT</Reference>... <LineItems> <LineItem ItemNumber="1"> <Description>Juliet of the Spirits</Description> <Part Id="37429165829" UnitPrice="29.95" Quantity="2"/> </LineItem> <LineItem ItemNumber="2"> <Description>Carl Th. Dreyer - My Metier</Description> <Part Id="37429161425" UnitPrice="0.0" Quantity="3"/> </LineItem> </LineItems></PurchaseOrder>HTTP/1.1 201 CreatedMS-Author-Via: DAVDAV: 1,2,<http://www.oracle.com/xdb/webdav/props>Date: Sat, 04 Apr 2009 23:14:20 GMTLocation: http://localhost/ds/users/sbell/orders/20030409123336231PDTServer: Noelios-Restlet-Engine/1.2snapshotAccept-Ranges: bytesContent-Type: text/plain; charset=ISO-8859-1Content-Length: 20

Updated 1 record(s).

Page 44: Native REST Web Services with Oracle 11g

Q & A

Thank you

Page 45: Native REST Web Services with Oracle 11g

Need more information?

OracleJVM and Java Stored Procedures http://www.oracle.com/technology/tech/java/jsp/index.html

Java Developer's Guide Java http://tahiti.oracle.com/pls/db111/to_toc?pathname=java.111/b31225/toc.htm

XMLDB Developer's Guide http://tahiti.oracle.com/pls/db111/to_toc?pathname=appdev.111/b28369/toc.htm

Restlet Framework http://www.restlet.org/

XDB Restlet Adapter http://wiki.restlet.org/docs_1.1/13-restlet/28-restlet/84-restlet.html

Data Service Example code http://dbprism.cvs.sourceforge.net/viewvc/dbprism/DataService/

My blog http://marceloochoa.blogspot.com/