REST Web Services

advertisement
Web Services with Apache CXF
Part 3: REST Web Services
Robert Thornton
Notes
•
•
•
•
•
This is a training, NOT a presentation
Please ask questions
This is being recorded
https://tech.lds.org/wiki/Java_Stack_Training
Prerequisites:
– Maven, Spring
– Web Application Development
– CXF Training, Parts 1 and 2
– Spring MVC, Part 2 (Recommended, but optional)
Objectives
At the end of this presentation, the participant will be able to:
• Understand the basics of the HTTP protocol.
• Understand how REST web services fit onto the HTTP protocol.
• Understand how the JAX-RS APIs and annotations can be used to
develop REST web services.
• Understand how CXF can be configured with Spring to produce
JAX-RS web services in a web application.
• Understand how JAX-RS differs and compares to Spring MVC
• Understand how to negotiate content in a JAX-RS service.
• Understand how to handle responses and exceptions in a JAX-RS
service.
Web Services with Apache CXF
REST Web Services
Part 1: Introduction to REST
Introduction to REST
REST stands for Representational State Transfer
• It is an architectural pattern for developing web services
as opposed to a specification.
• REST web services communicate over the HTTP
specification, using HTTP vocabulary:
– Methods (GET, POST, etc.)
– HTTP URI syntax (paths, parameters, etc.)
– Media types (xml, json, html, plain text, etc)
– HTTP Response codes.
Introduction to REST
• Representational
– Clients possess the information necessary to identify,
modify, and/or delete a web resource.
• State
– All resource state information is stored on the client.
• Transfer
– Client state is passed from the client to the service
through HTTP.
Introduction to REST
The six characteristics of REST:
1.
2.
3.
4.
5.
6.
Uniform interface
Decoupled client-server interaction
Stateless
Cacheable
Layered
Extensible through code on demand (optional)
* Services that do not conform to the above required
contstraints are not strictly RESTful web services.
Web Services with Apache CXF
REST Web Services
Part 2: HTTP and REST
HTTP-REST Request Basics
• The HTTP request is sent from the client.
– Identifies the location of a resource.
– Specifies the verb, or HTTP method to use when
accessing the resource.
– Supplies optional request headers (name-value pairs)
that provide additional information the server may
need when processing the request.
– Supplies an optional request body that identifies
additional data to be uploaded to the server (e.g.
form parameters, attachments, etc.)
HTTP-REST Request Basics
Sample Client Requests:
• A typical client GET request:
GET /view?id=1 HTTP/1.1
User-Agent: Chrome
Accept: application/json
[CRLF]
Requested Resource (path and query string)
Request Headers
(no request body)
• A typical client POST request:
Requested Resource (typically no query string)
POST /save HTTP/1.1
User-Agent: IE
Request Headers
Content-Type: application/x-www-form-urlencoded
[CRLF]
name=x&id=2
Request Body (e.g. form parameters)
HTTP-REST Response Basics
• The HTTP response is sent from the server.
– Gives the status of the processed request.
– Supplies response headers (name-value pairs) that
provide additional information about the response.
– Supplies an optional response body that identifies
additional data to be downloaded to the client (html,
xml, binary data, etc.)
HTTP-REST Response Basics
Sample Server Responses:
Response Status
HTTP/1.1 200 OK
Content-Type: text/html
Response Headers
Content-Length: 1337
[CRLF]
<html>
<!-- Some HTML Content. -->
Response Body (content)
</html>
HTTP/1.1 500 Internal Server Error
Response Status
Response Status
HTTP/1.1 201 Created
Location: /view/7
Response Header
[CRLF]
Some message goes here.
Response Body
HTTP-REST Vocabulary
HTTP Methods supported by REST:
• GET – Requests a resource at the request URL
– Should not contain a request body, as it will be discarded.
– May be cached locally or on the server.
– May produce a resource, but should not modify on it.
• POST – Submits information to the service for processing
– Should typically return the new or modified resource.
•
•
•
•
PUT – Add a new resource at the request URL
DELETE – Removes the resource at the request URL
OPTIONS – Indicates which methods are supported
HEAD – Returns meta information about the request URL
HTTP-REST Vocabulary
A typical HTTP REST URL:
http://my.store.com/fruits/list?category=fruit&limit=20
protocol
host name
path to a resource
query string
• The protocol identifies the transport scheme that will be used to
process and respond to the request.
• The host name identifies the server address of the resource.
• The path and query string can be used to identify and customize
the accessed resource.
HTTP and REST
A REST service framework provides a controller for
routing HTTP requests to a request handler
according to:
• The HTTP method used (e.g. GET, POST)
• Supplied path information (e.g /service/listItems)
• Query, form, and path parameters
• Headers, cookies, etc.
Producing REST Services
REST services in Java web applications can be
implemented in several ways:
• As a plain Java Servlet
– Adequate for very simple REST services.
– Requires a lot of “boiler plate” code for complex services.
• Using a REST service framework.
– Eliminates the need to write “boilerplate” code.
– Typically integrates with other technologies, such as Spring.
Java provides the JAX-RS specification for use by
providers of REST service frameworks.
REST on the Java Stack
Although developers may implement REST web
services however they choose, the Java Stack team
is best equipped to support the following:
• Apache CXF
– A JAX-RS web service framework
• Spring MVC
– An MVC framework built upon the Spring Platform
(does not implement the JAX-RS specification)
CXF Web Services Framework
Apache CXF is a robust framework designed specifically for
producing and consuming web services:
• It is open-source and free to use.
• It supports several web service standards and JSR APIs.
• It provides tooling and configuration for JAX-WS and
JAX-RS services.
• It provides integration with the Spring Application
Framework, the core technology upon which most of
the Java Stack is built.
CXF Web Services Framework
Apache CXF provides robust support for several web
service patterns and specifications:
• JSR APIs: JAX-WS, JAX-RS, JSR-181 annotations, SAAJ
• WS-* specifications for web service interoperability.
• Rich support support for message transports, protocol bindings,
content negotiation, data bindings, and so forth.
• Flexible, lightweight deployment in a variety of web application
containers or stand-alone.
• Tooling for code generation
• Tools for WSDL and WADL publishing.
REST Services with JAX-RS
JAX-RS is a Java standard API for REST services:
• Services are annotation driven
• Provides support for data binding.
• Provides advanced APIs for content negotiation.
CXF provides an implementation of JAX-RS:
• Supports CXF filters, interceptors, and invokers to
customize and extend the service.
• Configurable through Spring.
• Integrates with security providers.
REST Services with Spring MVC
Spring MVC is a model-view-controller framework
built upon the Spring Application Framework.
• Annotation driven
• Supports a RESTful pattern of routing requests to
web resources using HTTP vocabulary.
• Not an implementation of the JAX-RS
specification.
JAX-RS or Spring MVC?
Some Guidelines for choosing your solution:
• Both JAX-RS and Spring MVC can produce REST services.
• Spring MVC is a web application framework that can be used as service
framework.
– Provides better validation
– Supports internationalization
• JAX-RS is a primarily a services framework.
– Provides support for WADL generation
– Can use CXF interceptors, filters, etc.
• Match the framework to the needs and purpose of the project.
• Don’t mix both in same web application unless you need unique
features from each.
– If your project needs both, consider separate web applications.
• Consult the Java Stack team.
JAX-RS Basics
JAX-RS applications consist of a hierarchy of resources:
• Resources are served up by a CXF controller servlet.
• Each REST resource is mapped to a request URI that is relative to
the CXF controller servlet path.
• The relative path of each resource is mapped to a method on a
JAX-RS annotated service bean that returns the resource.
• Service bean methods that return a resource must be annotated
with a single JAX-RS HTTP method annotation (e.g @GET)
• Additional, optional annotations may be applied to the class, class
fields, and method parameters to customize the service API.
• JAX-RS service beans form the “view” or public interface of your
REST web service application.
JAX-RS Basics
An example REST service class:
package org.lds.tech.training.lab.ws;
import javax.ws.rs.GET;
import org.springframework.stereotype.Controller;
@Controller
public class HelloWebServiceRest {
@GET
public String sayHello() {
return "Hello, World!";
}
}
• At least one method must be annotated with an HTTP verb (e.g. @GET)
• The @Controller annotation makes the class discoverable by Spring
JAX-RS Basics
Example Spring configuration:
• Example location: WEB-INF/example-servlet.xml
<stack-rs:produce>
<stack-rs:interfaces>
<ref bean="helloWebServiceRest"/>
</stack-rs:interfaces>
</stack-rs:produce>
• A reference to the JAX-RS annotated service bean is passed to the
Stack RS “produce” namespace handler.
• Multiple service beans may be supplied under the Stack RS
“interfaces” element.
• Each bean will be scanned by CXF for annotated resources that
can be served up RESTfully.
JAX-RS Basics
Stack RS Namespace Usage:
• Element name: <stack-rs:produce/>
• Optional Attributes:
–
–
–
–
secured – whether to secure the endpoint
extensions – whether to support the use of .xml and .json extensions
address – the relative address of the REST service
authentication-manager-ref
• Child elements:
–
–
–
–
interfaces – JAX-RS annotated service beans
providers – provider beans for content negotiation
in-interceptors
out-interceptors
JAX-RS Basics
The JAX-RS resource hierarchy is described using “Web
Application Descriptor Language”, or WADL. Apache CXF
generates a WADL descriptor to expose the following
information about your service:
• All the resources available through REST calls.
• The relative path to each resource
• The HTTP method required to access each resource.
• How the HTTP response will represent, or format, each
resource.
JAX-RS Basics
An example WADL descriptor:
<application xmlns="http://wadl.dev.java.net/2009/02"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<resources
base="http://localhost:8080/example/Services/rest">
<resource path="/">
<method name="GET">
<response>
<representation mediaType="application/octet-stream">
<param name="result" style="plain" type="xs:string"/>
</representation>
</response>
</method>
</resource>
</resources>
</application>
JAX-RS: Lab 1
Lab 1: Hello World with REST
http://tech.lds.org/wiki/Web_Services_with_Apache_CXF_-_Part_3
JAX-RS Annotations
JAX-RS Annotations customize many parts of the
REST service:
• They identify the HTTP method for accessing a resource.
• They identify the relative path for accessing a resource.
• They identify how query and form parameters, headers,
cookies and other pieces of the HTTP request message
map to Java parameters and fields.
• They identify the available content types that can be
consumed or produced for a resource.
JAX-RS Method Annotations
JAX-RS HTTP Method Annotations:
@GET
@POST
@PUT
@DELETE
@OPTIONS
@HEAD
• Applied to a Java method to bind it to an HTTP method.
• Only one HTTP annotation may be applied to a single Java
method.
• Multiple Java methods may be given the same HTTP method
annotation, assuming they are bound to different paths.
JAX-RS @Path Annotation
• @Path annotations may be supplied to customize the
request URI of resource.
• @Path on a class defines the base relative path for all
resources supplied by that class.
• @Path on a Java class method defines the relative path for
the resource bound to that method.
• @Path on a method is relative to any @Path on the class.
• In the absence of @Path on the class or method, the
resource is defined to reside at the root of the service.
• A leading forward slash (/) is unecessary as the path is
always relative.
JAX-RS: @Path Annotation
The @Path annotation supports the use of template
parameters in the form:
•
•
•
•
{ name : regex }
The template parameter name is required.
The colon (:) followed by a regular expression is optional
and will default to the pattern: [^/]+
Multiple template parameters may be defined in a single
@Path.
Template parameter values will be injected into method
parameters annotated with @PathParam.
JAX-RS Parameter Annotations
• Common JAX-RS Parameter Annotations:
–
–
–
–
@QueryParam – maps to a query string parameter.
@FormParam – maps to a form POST parameter.
@PathParam – maps to a path segment.
@DefaultValue – supplies a default parameter value.
• Most often used on service methods to annotate input
parameters.
• Can also be used on fields or field setter methods if the
service bean has request scope.
• Additional parameter annotations are also available.
– See the JAX-RS API documentation for details.
JAX-RS Annotations: Examples
@Path("example")
public class ExampleWebServiceRest {
@GET
public Item getItem(@QueryParam("itemId") Long id) {
// @QueryParam example
}
@POST
public Response editItem(@FormParam("itemId") Long id,
@FormParam("value") String value) {
// @FormParam example
}
@GET
@Path("{category}/{subcategory:[^/]*}")
public List<Item> getItems(
@PathParam("category") String category) {
@PathParam("subcategory") String subcategory) {
// @Path and @PathParam example
}
}
JAX-RS Annotations: @Produces
@Produces
• Used on a class or method to identify the content types
that can be produced by that resource class or method.
• Method annotation overrides class annotation
• If not specified, CXF assumes any type (*/*) can be
produced.
• CXF responds with HTTP status “406 Not Acceptable” if
no appropriate method is found.
JAX-RS Annotations: @Consumes
@Consumes
• Used on a class or method to identify the content types
that can be accepted by that resource class or method.
• Method annotation overrides class annotation
• If not specified, CXF assumes any type (*/*) is
acceptable.
• CXF responds with HTTP status “406 Not Acceptable” if
no appropriate method is found.
JAX-RS Annotations
Examples of @Produces and @Consumes:
@Path("example")
public class ExampleRestService {
@POST
@Path("items")
@Produces({"application/json", "application/xml"})
@Consumes({"application/json", "application/xml"})
public List<Item> editItems(List<Item> items) {
// Does something and returns the modified list
}
}
• The client submits JSON or XML content with the “Content-Type”
header.
• The client requests either JSON or XML content through use of
the HTTP “Accept” request header.
JAX-RS: MessageBodyWriter
To produce content in other formats (as output), do the
following:
• Implement javax.ws.rs.ext.MessageBodyWriter for the Java
type that you want to write to the response.
• Annotate the implementation with @Provider
• Optionally annotate the implementation with @Produces to
restrict the content types for which it is suitable.
• Configure an instance of your provider as a Spring bean.
• Supply a reference to your bean under the <stackrs:providers> element of the <stack-rs:produce>
configuration.
JAX-RS: Example PDF Export
@Provider
@Produces("application/pdf")
public class PdfWriter implements MessageBodyWriter<MyCatalog> {
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true; // true means I can write the type to PDF
}
public long getSize(MyCatalog mc, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1; // Negative value means I don’t know yet
}
public void writeTo(MyCatalog mc, Class<?> type,
Type genericType, Annotation[] annot, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream)
throws IOException, WebApplicationException {
// Use iText to generate PDF and write to entityStream
}
}
JAX-RS: MessageBodyReader
To consume content in other formats (as input), do the
following:
• Implement javax.ws.rs.ext.MessageBodyReader for the
type that you want to read from the request.
• Annotate the implementation with @Provider
• Optionally annotate the implementation with @Consumes
to restrict the content types for which it is suitable.
• Configure an instance of your provider as a Spring bean.
• Supply a reference to your bean under the <stackrs:providers> element of the <stack-rs:produce>
configuration.
JAX-RS: Example Spreadsheet Import
@Provider
@Consumes(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public class SpreadSheetReader implements MessageBodyReader<MyCatalog> {
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true; // true means I can read the type as a spreadsheet
}
public MyCatalog readFrom(Class<MyCatalog> type,
Type genericType, Annotation[] annot, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException, WebApplicationException {
MyCatalog catalog = new MyCatalog()
// Use Apache POI, to read the spreadsheet and extract its data
return catalog;
}
}
JAX-RS: Example Configuration
The Stack RS namespace handler can be configured
to use your own custom providers:
<stack-rs:produce>
<stack-rs:interfaces>
<ref bean="catalogServiceRest"/>
</stack-rs:interfaces>
<stack-rs:providers>
<ref bean="pdfWriter"/>
<ref bean="xlsReader"/>
</stack-rs:providers>
</stack-rs:produce>
JAX-RS: XML and JSON Providers
• As a requirement of JAX-RS, CXF automatically
provides support for reading and writing XML to
and from JAXB annotated classes.
• CXF also provides built-in support for reading and
writing JSON to and from JAXB annotated
classes.
– Default support uses Jettison as the JSON provider
– The Stack RS namespace handler will automatically
configure Jackson as the JSON provider if it is on the
classpath.
JAX-RS: Lab 2
Lab 2: Using JAX-RS Annotations
http://tech.lds.org/wiki/Web_Services_with_Apache_CXF_-_Part_3
JAX-RS: Customizing the Response
There may be times when you need to customize the
response from your JAX-RS service, for example:
• To provide metadata instead of, or in addition to, the
response entity.
• To supply a custom status code
• To instruct CXF to perform a redirect.
For these cases, JAX-RS provides the abstract Response
class and the ResponseBuilder utility.
• An example is provided on the following screen.
JAX-RS: Customizing the Response
@Path("example")
@Produces({"application/json", "application/xml"})
@Consumes({"application/json", "application/xml"})
public class ExampleRestService {
@GET
public List<Item> getItems() {
// Return all items.
return items;
}
@POST
@Path("items")
public Response editItems(List<Item> items) {
// ... Modify the list of items
ResponseBuilder rb = Response.temporaryRedirect(
URI.create(UriInfo.getBaseUri() + "example"));
return rb.build(); // redirect to getItems()
}
}
JAX-RS: Exception Handling
By default, JAX-RS provides exception handling for
its own javax.ws.rs.WebApplicationException.
• Extends java.lang.RuntimeException
• May be thrown by any resource method
• Is converted by CXF into a Response object.
Any other exception will result in HTTP status “500
Internal Server Error”
JAX-RS: Custom Exception Handling
Custom exception handling can be provided by
doing the following:
• Implement javax.ws.rs.ext.ExceptionMapper for the
exception type you want to handle.
• Annotate the implementation class with @Provider
• Configure an instance of your provider as a Spring bean.
• Supply a reference to your bean under the <stackrs:providers> element of the <stack-rs:produce>
configuration.
JAX-RS: Custom ExceptionMapper
@Provider
public class TimeoutExceptionMapper
implements ExceptionMapper<TimeoutException> {
public Response toResponse(TimeoutException exception) {
ResponseBuilder rb = Response.status(408); // Request timeout
// Call additional methods on the response builder
// to further customize the response
return rb.build();
}
}
JAX-RS: Lab 3
Lab 3: Custom Response and Exception Handling
http://tech.lds.org/wiki/Web_Services_with_Apache_CXF_-_Part_3
Conclusion
JAX-RS is a flexible API for providing scalable web
services.
CXF, Spring and the Java Stack integrate to make
developing and configuring REST services easy.
Many aspects of the request, response, and
exception handling can be customized through use
of MessageBodyReader, MessageBodyWriter,
ResponseBuilder, and ExceptionMapper.
Credit
Resources used to prepare this training:
• http://cxf.apache.org
• http://en.wikipedia.org/wiki/Representational_state_transfer
• Java 6 API Documentation
• Java Stack Documentation
• W3C HTTP Method Specification
• Spring MVC Training, Part 2, by Spencer Uresk
Download