Download - Thinking restfully
![Page 1: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/1.jpg)
JHUG 17 Dec 2011
REST Thinking RESTfully Stelios Gkorilas
![Page 2: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/2.jpg)
JHUG 17 Dec 2011
Contents 1. Types of services 2. What is REST? 3. Web services and the REST way 4. Example: S3 5. Security 6. Jersey/JAX-RS 7. CTR
![Page 3: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/3.jpg)
JHUG 17 Dec 2011
Distributed services • The everlasting need to (re-)use logic as black box
• Even across different machines and platforms • Gave birth to distributed objects and several protocols for
remoting (e.g. CORBA, DCOM, RMI) • Web services prevailed because the web is ubiquitous and
scalable • Web services provide the means to integrate disparate systems
and expose reusable business functions over HTTP • Mostly SOAP services up to now in RPC style
• Some serve HTML, JSON, plain text, or binary documents, but most use XML
• WSDL and the WS-* specs • HTTP is used as the transport service not the application protocol
![Page 4: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/4.jpg)
JHUG 17 Dec 2011
Service styles • RPC services • Message oriented services • Resource oriented services
![Page 5: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/5.jpg)
JHUG 17 Dec 2011
RPC style • The request message identifies the procedure to be
executed, and the fixed set of parameters that map directly to the parameters of the remote procedure
• XML-RPC and later the WS-* stack
• Procedure arguments are tightly coupled messages • Usually flat APIs • Communication through proxies that have to be
regenerated in case of change • e.g. JAX-WS
![Page 6: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/6.jpg)
JHUG 17 Dec 2011
Message oriented • Services that have Message APIs (a.k.a. Document APIs)
receive one or more self-descriptive message types at a given URI
• They are not coupled to procedure names hence they can easier change
• They can constitute commands, events or just documents • They contain values that identify their type and/or
handling
![Page 7: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/7.jpg)
JHUG 17 Dec 2011
making a Google search the SOAP way POST search/beta2 HTTP/1.1 Host: api.google.com Content-Type: application/soap+xml SOAPAction: urn:GoogleSearchAction <?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body> <gs:doGoogleSearch xmlns:gs="urn:GoogleSearch"> <key>00000000000000000000000000000000</key> <q>jhug user group</q> <start>0</start> <maxResults>10</maxResults> <filter>true</filter> <restrict /> <safeSearch>false</safeSearch> <lr /> <ie>latin1</ie> <oe>latin1</oe> </gs:doGoogleSearch></soap:Body>
</soap:Envelope>
![Page 8: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/8.jpg)
JHUG 17 Dec 2011
Resource oriented • It’s like object oriented – Resources are objects • Resource is the design of data; what we perceive data to
be; it is what we think others might find interesting about our data
• Everything can be a resource • Resources are accessed through a Uniform Interface • Resources are interconnected • Resources have multiple representations • Communication is stateless
![Page 9: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/9.jpg)
JHUG 17 Dec 2011
Resources • Everything can be a resource (like everything can be an object) • A procedure, instances of domain data, files • Examples:
• A list of search results about ‘Mullus barbatus’ • An article • The jhug meeting on Dec 17 • The latest jhug meeting • The software version release 1.1.2.3 • The latest release • The list of unresolved issues of type ‘bug’ and component ‘Launcher’
• Every resource should have a unique identifier, a URI • http://www.jhug.gr/meetings/meet-up/17-dec-2011
![Page 10: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/10.jpg)
JHUG 17 Dec 2011
What is REST? • Architectural style • Architectural constraints • A way to evaluate architectures • Design principles • Key properties of a simple (not simplistic) application • The null style: Start with system needs as a whole,
without constraints, and then incrementally identifies and applies constraints to elements of the system in order to differentiate the design space
• Representational State Transfer • You request a resource and a representation of its state is
returned
![Page 11: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/11.jpg)
JHUG 17 Dec 2011
HTTP Example Request GET /meetups/latest HTTP/1.1 Host: www.jhug.gr Accept: application/xml
Response HTTP/1.1. 200 OK Date: Sat, 17 Dec 2011 13:45:34 GMT Server: Apache/1.3.6 Content-Type: application/xml; charset=UTF-8 <?xml version="1.0" encoding="UTF-8"?> <meetup xmlns="...">
<occurred date=".."/> <presentations> ... </presentations> <next uri=".."/>
</meetup>
![Page 12: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/12.jpg)
JHUG 17 Dec 2011
HTTP, URIs & XML define the web • Operations: GET, PUT, DELETE, POST
• And the less known HEAD, OPTIONS • Headers
• content-type • Accept-Language
• Media types • text/plain • text/xml • application/atom+xml
• Response codes • 2xx Success • 3xx Redirect • 4xx Client Error • 5xx Server Error
• URIs and URLs define the web
• XML: content attributes and structure
An Application protocol for service logic
![Page 13: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/13.jpg)
JHUG 17 Dec 2011
REST constraints (Fielding dissertation) • Client/server • Uniform Interface • Layered System • Stateless • Cache • Code on Demand
![Page 14: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/14.jpg)
JHUG 17 Dec 2011
Resources and the uniform interface • HTTP standard methods: GET, PUT, POST, DELETE • HEAD and GET should not modify anything • Idempotent: PUT DELETE GET HEAD
• HTTP is the application protocol defining service behaviors
• GET /meetups/latest instead of getLatestMeetup() • RPC verbs become REST nouns
• GET the more recent state of the resource • PUT/POST a representation that alters the state of the
resource
![Page 15: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/15.jpg)
JHUG 17 Dec 2011
Representations • Representations have media types • Multiple formats for different needs
• Content negotiation • Accept: application/json (request) • Content-Type: application/json (response)
• URI • /meetups/latest.json
![Page 16: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/16.jpg)
JHUG 17 Dec 2011
Addressability • Representations should be addressable • Increase the surface of the service
• Client can enter the application where convenient
• A URI can never point to more than one resource
![Page 17: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/17.jpg)
JHUG 17 Dec 2011
Interconnected Resources • Resources are not just data but hypermedia • Hypermedia as the engine of state • Representations contain links to other resources • A representation may contain links ot other states of the resource • Paths a client can follow • Makes clients more resilient to changes <?xml version="1.0" encoding="UTF-8"?> <meetup xmlns="...">
<occurred date="17-12-2011"/> <presentations> <presentation ref="/presentations/title/disruptor"/> <presentation ref="/presentations/title/rest"/> <presentation ref="/presentations/title/sw-dev-practices"/> </presentations> <next ref="/meetings/date/17-01-2011"/>
</meetup>
![Page 18: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/18.jpg)
JHUG 17 Dec 2011
Stateless • HTTP is stateless • All information needed for processing part of the request • No session on the server
• No session ids exchanged (jsessionId, phpSessionId, etc. )
• Application state belongs to the client • Resource state alone belongs to the server
• Simplifies server and client logic, allows scalability e.g. http://www.google.gr/search?q=jhug&start=20
![Page 19: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/19.jpg)
JHUG 17 Dec 2011
Cacheability • Conditional queries
• Cacheable when last-modified and etag are used (response headers)
• If- Modified-Since and If-None-Match (request headers) • 304 Response Code when not modified with no entity body
• Cache proxies and other commodity caching technologies
![Page 20: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/20.jpg)
JHUG 17 Dec 2011
REST Patterns • Paths for hierarchy
• jhug/discussions/april
• Post for not owned URIs • Container items • Jhug/discussions/1342
• PUT for URIs defined by the client • Jhug/presentations/rest
• Semicolon (;) or comma (,) for name/value or matrix values • jhug/presentations/author,gkorilas/rest
• Query string for algorithmic resources • Jhug/search?q=“rest”
![Page 21: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/21.jpg)
JHUG 17 Dec 2011
Think Resource Oriented • Define the data set • Expose data as resources • Assign URIs to resources • Decide the UI commands accepted • Decide the representations accepted • Decide the representations served • Add hypermedia links between them
![Page 22: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/22.jpg)
JHUG 17 Dec 2011
REST + • Serve representations suitable for many clients
• The uniform interface allows all http clients to easily consume a suitable representation
• Content negotiation can allow a single URL to serve content to a browser, a JS client that is interested in JSON or a mobile phone client interested in an XML representation
• Cacheable by commodity technologies • Scalable • Fail over • Clients:
• Browser friendly • Easy support by many languages • Bookmarkable • Data formats
• It is the natural way of the web!
![Page 23: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/23.jpg)
JHUG 17 Dec 2011
REST Security standards
![Page 24: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/24.jpg)
JHUG 17 Dec 2011
The Amazon S3 Service • S3 “buckets” and S3 “objects”
• Bucket can only contain objects • Bucket names are unique in S3 • Object has a name (key) and content (value) • Object has a reference to the parent bucket • Object has metadata key-value pairs; can also be http headers like
content-type or content-disposition
• Three types of resources • List of your buckets (https://s3.amazonaws.com/) • A particular bucket (https://s3.amazonaws.com/{name-of-bucket}/). There
can be up to 100 resources of this type. • A particular S3 object inside a bucket (https://s3.amazonaws.com/
{name-of- bucket}/{name-of-object}
![Page 25: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/25.jpg)
JHUG 17 Dec 2011
S3 resources and methods GET HEAD PUT DELETE
(/) List your buckets
- - -
/{bucket} List objects of bucket
- Create the bucket
Delete the bucket
/{bucket}/{object}
Object’s value and metadata
Object’s metadata
Set the object’s value and metadata
Delete the object
![Page 26: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/26.jpg)
JHUG 17 Dec 2011
S3 Security • Message digest of the canonical string of the request with a
secret key (amazon knows it too) • {http method}{content-type}{date}{amazon headers}{path}
• Add it to http Authorization: header
• Add it to query string together with expires date to make bookmarkable (https://s3.amazonaws.com/stelinio/rest.pdf# ?Signature=J%2Qu6krT3j0zaaFXjsLbowdfzExQ%3D # &Expires=1162156788&AWSAccessKeyId=0F9RBCLB5274NKTJ4DA3")
• Access policies • Private, public-read, public-write, authenticated read
![Page 27: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/27.jpg)
JHUG 17 Dec 2011
HTTP security, OAuth • http basic • http digest • http client certificate
• OAuth • Delegated user authentication solution - Valet key principle • Client, server, resource owner (OAuth love triangle) • client credentials, temporary credentials, and token credentials
![Page 28: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/28.jpg)
JHUG 17 Dec 2011
Java REST Services • Java EE 6 specification: JAX-RS • Jersey: Reference implementation of JSR 311 • Available as standalone and enterprise
![Page 29: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/29.jpg)
JHUG 17 Dec 2011
Standalone example setup <servlet>
<servlet-name>jersey</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>eu.ema.eudract.rest</param-value> </init-param> <load-on-startup>1</load-on-startup>
</servlet> <dependency>
<groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId>
</dependency> <dependency>
<groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId>
</dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-atom</artifactId> </dependency>
![Page 30: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/30.jpg)
JHUG 17 Dec 2011
JAX-RS Resources Annotate POJOs @Path("/meetups")@Singleton()public class MeetUpsResource {
@GET()@Path("/latest")@Produces("text/plain")public String getLatestMeetUp() { return getDataService().getLatestMeetUp().toString();}
@GET()@Path("/next")@Produces("text/plain")public String getNextMeetUp() { return getDataService().getNextMeetUp().toString();}@GET()@Produces(MediaType.APPLICATION_JSON)public MeetUps getAllMeetUps() { return getDataService().getAllMeetUps();}
}
![Page 31: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/31.jpg)
JHUG 17 Dec 2011
Methods & Paths • @javax.ws.rs.GET • @javax.ws.rs.PUT • @javax.ws.rs.POST • @javax.ws.rs.DELETE • @javax.ws.rs.HEAD
• Paths: Most specific match wins
![Page 32: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/32.jpg)
JHUG 17 Dec 2011
JAX-RS Injection • @javax.ws.rs.PathParam
• values from URI template parameters • @javax.ws.rs.MatrixParam
• URI’s matrix parameters. • @javax.ws.rs.QueryParam
• Query String parameters • @javax.ws.rs.FormParam
• form-encoded key-value pairs • @javax.ws.rs.HeaderParam
• HTTP request headers • @javax.ws.rs.CookieParam
• HTTP cookies set by the client • @javax.ws.rs.core.Context
• All-purpose injection annotation. It allows you to inject various helper and informational objects that are provided by the JAX-RS API e.g.
• @Context final HttpServletRequest request• @Context final SecurityContext secCtx
![Page 33: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/33.jpg)
JHUG 17 Dec 2011
JAX-RS Content Handling • MIME types • Automatic content negotiation • Automatic content serialization
• Jaxb representation → XML, JSON • Byte[] → Binary or */* • String → text/* • MultiValuedMap<String, String> → application/x-www-form-
urlencoded
• StreamingOutput • @Providers
![Page 34: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/34.jpg)
JHUG 17 Dec 2011
JAX-RS Error Handling • HTTP Error Codes • WebApplicationException • ExceptionMapper
throw new WebApplicationException(new RuntimeException (“Timeframe not an Integer"),
Response.Status.NOT_ACCEPTABLE);@Provider public class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException>{ public Response toResponse(EntityNotFoundException e){
return Response.status(Response.Status.NOT_FOUND).build(); }
}
![Page 35: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/35.jpg)
JHUG 17 Dec 2011
Enforcing security • @RolesAllowed({“admin”,”client-admin”}) • @PermitAll
• Any authenticated user • @SecurityContext
public interface SecurityContext{ public static final String BASIC_AUTH = "BASIC"; public static final String CLIENT_CERT_AUTH = "CLIENT_CERT"; public static final String DIGEST_AUTH = "DIGEST"; public static final String FORM_AUTH = "FORM"; public Principal getUserPrincipal(); public boolean isUserInRole(String role); public boolean isSecure(); public String getAuthenticationScheme();}
![Page 36: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/36.jpg)
JHUG 17 Dec 2011
Example @Path(”/presentations")@Singleton()public class PresentationsResource {
@PUT()@Path(”/presentation/{name}”)@RolesAllowed(”admin”)public void addPresentation(@PathParam name, InputStream is){ return getDataService().addPresentation(is);}
@GET()@Path(”/presentation/{name}")public StreamingOutput getPresentation(@PathParam name) { return new StreamingOutput() { @Override public void write(OutputStream output) throws IOException {
stream( getDataService().getPresentation(name) , output ); } }
}
}
![Page 37: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/37.jpg)
JHUG 17 Dec 2011
CTR • Clinical Trials Register
• (https://www.clinicaltrialsregister.eu/)
• Rest services • Data to other agency html pages • Content to the World Health Organization • Data to the web application users
• Rest clients • JS code as the client • Controller servlet • JSP <c:import url=“/trial/2010-022009-16/GB”/> • A guy at World Health Organization every Tuesday at 19:00
![Page 38: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/38.jpg)
JHUG 17 Dec 2011
Data consumed by html pages (1/3) @Path("/trials")@Singleton()public class TrialsMetaDataResource {
@GET()@Path("/count/public")@Produces("text/plain")public String countPublicTrials() { return getDataService().countPublicClinicalTrials().toString();}
@GET()@Path("/count/public/under18")@Produces("text/plain")public String countUnder18PublicTrials() { return getDataService().countPublicClinicalTrialsWithSubjectsUnder18().toString();}@GET()@Path("/landing")@Produces(MediaType.APPLICATION_JSON)public LandingPageMetadata landingPageMetadata() { Integer total = getDataService().countPublicClinicalTrials(); Integer under18 = getDataService().countPublicClinicalTrialsWithSubjectsUnder18(); LandingPageMetadata metadata = new LandingPageMetadata(total, under18); return metadata;}
…}
![Page 39: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/39.jpg)
JHUG 17 Dec 2011
Data consumed by html pages (2/3) @XmlRootElement()@XmlAccessorType(value = XmlAccessType.PROPERTY)public class LandingPageMetadata implements Serializable {
private static final long serialVersionUID = -8784258618018188874L;
private Integer numberOfPublicClinicalTrials;private Integer numberOfPublicClinicalTrialsWithSubjectsUnder18;
public LandingPageMetadata() {…}
public LandingPageMetadata(Integer numberOfPublicClinicalTrials, Integer numberOfPublicClinicalTrialsWithSubjectsUnder18) {…}@XmlElement(name="total")public Integer getNumberOfPublicClinicalTrials() {…}public void setNumberOfPublicClinicalTrials(Integer numberOfPublicClinicalTrials) {…}
@XmlElement(name="under18")public Integer getNumberOfPublicClinicalTrialsWithSubjectsUnder18() {…}
public void setNumberOfPublicClinicalTrialsWithSubjectsUnder18(Integer
numberOfPublicClinicalTrialsWithSubjectsUnder18) {…}
@Overridepublic String toString() {…}
}
![Page 40: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/40.jpg)
JHUG 17 Dec 2011
Data consumed by html pages (3/3) function showNumbers() {
$.getJSON('api/trials/landing', function(data) { var total = data['total']; var under18 = data['under18']; $("#total").text(total); $("#under18").text(under18);});
}
![Page 41: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/41.jpg)
JHUG 17 Dec 2011
Streaming Content (1/2) @Path("/download")public class DownloadResource {
@GET@Path("/summary")public Response downloadSummaryTrials(@Context final HttpServletRequest request, @QueryParam ("mode") final String mode) {return Response.ok(new SummaryStreamingOutput(request, mode),MediaType.APPLICATION_OCTET_STREAM) .header("content-disposition","attachment; filename = trials-summary.txt").build();}@GET@Path("/full")public Response downloadFullTrials(@Context final HttpServletRequest request, @QueryParam ("mode") final String mode) {return Response.ok(new FullStreamingOutput(request, mode),MediaType.APPLICATION_OCTET_STREAM) .header("content-disposition","attachment; filename = trials-full.txt").build();}@GET@Path("/trial/{eudractnumber}/{nca}")public Response downloadFullCta(@Context final HttpServletRequest req, @PathParam ("eudractnumber") String eudractnumber, @PathParam("nca") String nca) {return Response.ok(new CtaStreamingOutput(req, eudractnumber, nca),MediaType.APPLICATION_OCTET_STREAM) .header("content-disposition","attachment; filename = trial.txt").build();}
}
![Page 42: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/42.jpg)
JHUG 17 Dec 2011
Streaming Content (2/2) public class CtaStreamingOutput implements StreamingOutput{
public CtaStreamingOutput(HttpServletRequest request, String euNumber, String nca) {…}
public void write(OutputStream output) throws IOException { TextSerializer ser = new TextSerializer(); ser.setOutputStream(output); CtaIdentification pubCta = mapper.map (eudractNumber, nca); ser.serializeCtaFull(pubCta);}
}
![Page 43: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/43.jpg)
JHUG 17 Dec 2011
RSS 2.0 instead of built in Atom (1/2) @GET@Path("/bydates”)@Produces("application/rss+xml")public SyndFeed getFeed(@Context final HttpServletRequest request) {
String feedType = "rss_2.0”;SyndFeed feed = new SyndFeedImpl();feed.setFeedType(feedType);String url = request.getRequestURL().toString().replaceFirst("/rest/ feed/bydates", ”/search") + "?" + request.getQueryString();feed.setLink(url);feed.setTitle("EU Clinical Trials Register RSS Feed");feed.setDescription("This provides a regular feed of new or updated clinical trial information published on the EU Clinical Trial Register and matching the search subscribed to.");List<CtrDocument> docs = search(request); for(CtrDocument doc: docs){ SyndEntry entry = buildEntry(doc, entryBasicUrl, countryUrl); feed.getEntries().add(entry);}LOG.info("Generated RSS feed {}", feed.getLink());return feed;
}
![Page 44: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/44.jpg)
JHUG 17 Dec 2011
RSS 2.0 instead of built in Atom (2/2) @Provider@Produces("application/rss+xml")@Consumes("application/rss+xml")public class RomeRssSupport implements MessageBodyWriter<Object>{
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {return (SyndFeed.class.isAssignableFrom(type));
}
public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {return -1;
}
public void writeTo(Object feedOrEntry, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream outputStream) throws IOException {if (feedOrEntry instanceof SyndFeed) { SyndFeed feed = (SyndFeed)feedOrEntry; SyndFeedOutput output = new SyndFeedOutput(); doc = output.outputW3CDom(feed); Source source = new DOMSource(doc); Result result = new StreamResult(outputStream); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.transform(source, result); }
}}
![Page 45: Thinking restfully](https://reader036.vdocuments.us/reader036/viewer/2022081400/554f8410b4c905435d8b4ae9/html5/thumbnails/45.jpg)
JHUG 17 Dec 2011
Resources
ptg6899256
• Restful Web Services - Leonard Richardson and Sam Ruby
• Service Design Patterns - Robert Daigneau • Restful Java - Bill Burke • www.amazon.com • http://icondrawer.com • http://www.iconeden.com • http://www.iconshock.com