Software
Version: 0.1
The Apache Wink User Guide document
is a broad scope document that provides detailed information about the Apache Wink
0.1 design and implementation.
2..... Apache Wink Architecture
2.1. Wink Runtime Architecture Overview
3..... Registration and Configuration
3.1.1. Specifying the Simple Application File Location
3.5.1. Custom Properties File Definition
4.2. The “alt” Query Parameter
4.5. Generating Absolute or Relative Links
5.3.1. Entity Producing Methods
5.3.2. Entity Consuming Methods
5.8.1. Request Entity Matching
5.8.2. Response Entity Matching
6.3. Out-of-the-Box Implementations
7.1.1. @Workspace Annotation Example
8..... Resource Matching - Continued Search
8.1. Resource Matching Overview
9.5. Atom Publishing Protocol (APP)
9.6. Comma Separated Values (CSV)
10.1. Enabling the APP Service Document Auto Generation
10.2. Adding Resources to APP Service Document
10.3. APP Service Document HTML Styling
11.1.1. Spring Context Loading
11.1.2. Registering Resources and Providers
11.2. Custom Properties File Definition
11.3. Customizing Media-Type Mappings
11.4. Customizing Alternative Shortcuts
11.4.1. External Properties File
12.3. Resource Method Definition
12.4. Creating a Multistatus Response
12.4.1. Using WebDAVResponseBuilder
12.4.2. WebDAVResponseBuilder Example
13.3.1. System Request Handlers
13.4.1. System Response Handlers
13.4.2. User Response Handlers
14.1. This chapter contains the following sections
14.6. High Level Architecture Overview
14.7. Getting Started with the Wink Client
14.8.3. Apache Http Client Configuration
14.8.4. Custom Provider Configuration
14.9.2. Custom Handler Implementation
14.9.3. Input and Output Stream Adapters
14.9.4. Stream Adapters Example
Table 1: Deployment Configuration Customizable Methods
Table 2: Wink Customization Properties
Table 6: AtomFeedSyndFeedProvider
Table 7: AtomFeedJAXBElementProvider
Table 9: AtomEntrySyndEntryProvider
Table 10: AtomEntryJAXBElementProvider
Table 12: AppCategoriesProvider
Table 14: OpenSearchDescriptionProvider
Table 17: JsonSyndEntryProvider
Table 18: JsonSyndFeedProvider
Table 21: HtmlSyndEntryProvider
Table 23: CsvSerializerProvider
Table 24: CsvDeserializerProvider
Table 25: @Workspace Annotation Specification
Table 26: @Asset Annotation Specification
Table 27: @Scope Annotation Specification
Table 28: @Parent Annotation Specification
The purpose of this document is to provide detailed information about Wink and describe the additional features that the Wink runtime provides in addition to the JAX-RS Java API for REST Web Service specification.
In addition to the features description, this document also provides information regarding implementation specific issues.
This document provides the developer with a rudimentary understanding of the Wink implementation in order to highlight the underlying concepts and precepts that make up the framework to create a basis for understanding, cooperation and open development of Wink.
|
This User Guide is a Preliminary Draft This document a preliminary draft and is subject
to change in future a release. |
In order to understand the contents of this
document the reader is required to have read the JAX-RS v1.0 specification and
have a rudimentary understanding of the specification and the terminology used
to describe the feature set.
For more information on the JAX-RS functionality, refer to the JAX-RS specification document, available at the following location: http://jcp.org/aboutJava/communityprocess/final/jsr311/index.html |
Apache Wink 0.1 is a complete and TCK compliant implementation of the JAX-RS v1.0 specification.
The following chapter describes the basic concepts and building blocks of Wink and explains the high-level architecture of the Wink runtime.
2.1. Wink Runtime Architecture Overview
The Wink runtime is deployed on a JEE environment and is
configured by defining the RestServlet in the web.xml file of the
application. This servlet is the entry point of all the Http requests targeted
for web services, and passes the request and response instances to the Wink
engine for processing.
Figure 1: Request Processor Architecture
The above diagram illustrates the core components of the Wink runtime. The Wink engine is the RequestProcessor. It builds an instance of a MessageContext with all of the required information for the request and passes it through the engine handler chains. The handler chains are responsible for serving the request, invoking the required resource method and finally for generating a response.
In case of an error, the RequestProcessor invokes the Error chain with the generated exception for producing the appropriate response.
The Wink runtime maintains providers and resources in two registries, the Providers Registry and the Resource Registry utilizing them during request processing.
The RequestProcessor is the Wink engine that is initialized by the RestServlet and is populated with an instance of a DeploymentConfiguration.
When a request is passed to the handleRequest() method of the RequestProcessor, a new instance of a MessageContext is created.
The MessageContext contains all of the information that is required for the Wink runtime to handle the request. The RequestProcessor first runs the Request Handler Chain to invoke the resource method and then the Response Handler Chain to produce the response.
If an exception occurs during any stage of the request processing, the RequestProcessor invokes the Error Handler Chain for processing the exception.
The Wink runtime is initialized with an instance of a DeploymentConfiguration. The Deployment Configuration holds the runtime configuration, including the handler chains, registries and configuration properties.
The Deployment Configuration is initialized with an instance of a JAX-RS Application used for obtaining user resources and providers.
The Deployment Configuration is customized by extending the DeplymentConfiguration class, overriding specific methods and specifying the new class in the web.xml file of the application.
In order to specify a different Deployment Configuration class instead of the default Deployment Configuration, the value of the deploymentConfiguration init parameter must be set to be the fully qualified name of the customized configuration class.
<servlet> <servlet-name>restSdkService</servlet-name> <servlet-class> org.apache.wink.server.internal.servlet.RestServlet </servlet-class> <init-param> <param-name>deploymentConfiguration</param-name> <param-value>org.apache.example.MyDeploymentConfig</param-value>
</init-param> </servlet> |
The following table details the customizable methods of the DeploymentConfiguration class.
Deployment
Configuration
Table 1: Deployment
Configuration Customizable Methods
Method |
Description |
initAlternateShortcutMap |
Initializes the AlternateShortcutMap. Refer to section 3.8 |
initMediaTypeMapper |
Initializes the MediaTypeMapper. Refer to section 3.7 |
initRequestUserHandlers |
Return a list of User Handler instances to embed in the Request chain. Refer to section 13.3 |
initResponseUserHandlers |
Return a list of User Handler instances to embed in the Response chain. Refer to section 13.4 |
initErrorUserHandlers |
Return a list of User Handler instances to embed in the Error chain. Refer to section 13.5 |
The handler chain pattern is used by the Wink runtime for implementing the core functionalities.
There are three handler chains utilized by the Wink runtime:
·
RequestHandlersChain
·
ResponseHandlersChain
·
ErrorHandlersChain
Refer to chapter 13 for more information on Handler Chains. |
The Wink runtime utilizes two registries for maintaining the JAX-RS resources and providers. Both registries maintain their elements in a sorted state according to the JAX-RS specification for increasing performance during request processing. In addition to the JAX-RS specification sorting, Wink supports the prioritization of resources and providers.
Refer to chapter 3, section 3.4 for more information on Priorities. |
Figure 2: Resource Registry
The resources registry maintains all of the root resources in the form of Resource Records.
A Resource Record holds the following:
· URI Template Processor – represents a URI template associated with a resource. Used during the resource matching process.
· Resource Metadata – holds the resource metadata collected from the resource annotations.
· Sub-Resource Records – records of all the sub-resources (methods and locators) collected from the sub-resource annotations.
· Resource Factory – a factory that retrieves an instance of the resource in accordance to the creation method defined for the resource. Possible creation methods include:
— singleton
— prototype
— spring configuration
— user customizable
The providers registry maintains of all of the system and user providers and manages them in an efficient way.
3. Registration and Configuration
Wink provides several methods for registering resources and providers. This chapter describes registration methods and Wink configuration options.
Wink provides the SimpleWinkApplication class in order to support the loading of resources and providers through a simple text file that contains a list of fully qualified class names of the resource and provider classes.
Each line contains a single fully qualified class name that is
either a resource or a provider. Empty lines and lines that begin with a number
sign (#) are permitted and ignored.
com.example.MyXmlProvider com.example.MyJSONProvider # Resources com.example.FooResource com.example.BarResource |
3.1.1. Specifying the Simple Application
File Location
The path to a simple application file is configured via the applicationConfigLocation
init-param in the web.xml file. It is possible to specify multiple files by
separating them with a semicolon.
<servlet-name>restSdkService</servlet-name> <servlet-class> org.apache.wink.server.internal.servlet.RestServlet </servlet-class> <init-param> <param-name>applicationConfigLocation</param-name> <param-value>/WEB-INF/providers;/WEB-INF/resources</param-value> </init-param> </servlet> |
Wink extends the javax.ws.rs.core.Application
class with the org.apache.wink.common.WinkApplication
class in order to provide the Dynamic Resources and the Priorities
functionality.
Refer to chapter 3, sections 3.3
and 3.4
for more information on Dynamic Resources and Priorities. |
An application may provide an instance of WinkApplication to the Wink runtime as
specified by the JAX-RS specification.
Dynamic Resources enable the binding of a Resource class to a URI path during runtime instead of by using the @Path annotation. A dynamic resource must implement the org.apache.wink.server.DynamicResource interface and must not be annotated with the @Path annotation.
A Dynamic Resource is
useful for situations where a resource class must be bound to multiple paths, for
example, a sorting resource:
public class SortingResource<E extends Comparable<? super E>> { private
List<E> list; @POST public
void sort() { Collections.sort(list); } public
void setList(List<E> list) { this.list = list; } public
List<E> getList() { return
list; } } |
In this example, the SortingResource class can sort any list. If the
application manages a library of books and exposes the following resource paths,
then the SortingResource class can be used for the implementation of all these
resource paths, assuming that it could be bound to more than one path.
/sort-books /sort-authors /sort-titles |
A dynamic resource is also useful for situations where the resource path is unknown
during development, and is only known during the application startup.
A Dynamic Resource is a resource class that implements the org.apache.wink.server.DynamicResource interface or extends the org.apache.wink.server.AbstractDynamicResource convenience class.
A Dynamic Resource is not registered in Wink through the Application#getClasses() method or the Application#getSignletons() method, since the same class can be used for multiple resources.
In order to register Dynamic
Resources in the system, the WinkApplication#getInstances()method must be used.
Refer to chapter 3, section 3.2 for more information about Wink Application. |
The scope of a Dynamic Resource is limited to singleton as it is initialized prior to its registration, and the system does not have enough information to create it in runtime. This limitation is irrelevant when working with Spring.
Refer to chapter 11 for more information about Spring Integration. |
Although JAX-RS defines the algorithm for searching for resources and providers, Wink extends this algorithm by providing the ability to specify priorities on them. This is achieved by enabling the registration of multiple Application instances with different priorities, rendering the order of their registration irrelevant as long as they have different priorities.
In order to register a prioritized Application, it is necessary to register an instance of a WinkApplication class.
Priority values range between 0 and 1. In the event that the priority was not specified, a default priority of 0.5 is used.
Priorities on resources are useful in situations where an application registers core resources bound to paths, and allows extensions to register resources on the same paths in order to override the core resources.
The Wink runtime first sorts the resources based on their priority and then based on the JAX-RS specification, thus if two resources have the same path, the one with higher priority is invoked.
JAX-RS requires that application-provided providers be used in preference to implementation pre-packaged providers. Wink extends this requirement by allowing applications to specify a priority for providers.
The Wink runtime initially sorts the matching providers according to the JAX-RS specification, and uses the priority as the last sorting key for providers of equal standing.
If two providers have the same priority, the order in which they are registered determines their priority such that the latest addition receives the highest priority.
In order to meet the JAX-RS requirements, the pre-packages providers are registered using a priority of 0.1.
Wink provides a properties file in order to enable simple customizations. By default, Wink predefines default values for all possible properties.
Customization
Properties
Table 2: Wink Customization Properties
Property Name |
Description |
Default Value |
Ref |
wink.http.uri |
URI that is used by the Link Builders in case of HTTP |
Use the URI from the request. |
chapter 4 |
wink.https.uri |
URI used by the Link Builders in case of HTTPS. |
Use the URI from the request. |
chapter 4 |
wink.context.uri |
Context path used by the Link Builders. |
Use the context path from the request. |
chapter 4 |
wink.defaultUrisRelative |
Indicates if URIs generated by the Link Builders are
absolute or relative. Valid values: true or false |
true – links will be relative. |
chapter 4 |
wink.addAltParam |
Indicates if the “alt” query parameter should be added to URIs
generated by the Link Builders. Valid values are: true, false. |
true – add the alt query parameter |
chapter 4 |
wink.searchPolicyContinuedSearch |
Indicates if continues search is enabled. Valid values:
true, false |
false – continued search is disabled. |
chapter 8 |
wink.rootResource |
Indicates if a root resource with Service Document generation capabilities should be added. Valid values are: none, atom, atom+html |
atom+html –atom and HTML Service Document generation capabilities |
chapter 10 |
wink.serviceDocumentCssPath |
Defines path to a css file that is used in the HTML
Service Document generation. Relevant only if HTML Service Document is
defined. |
No css file defined. |
chapter 10 |
3.5.1. Custom Properties File
Definition
In order to provide a custom properties file, the application
should define the propertiesLocation init-param in the Wink Servlet
definition.
<servlet-name>restSdkService</servlet-name> <servlet-class> org.apache.wink.server.internal.servlet.RestServlet </servlet-class> <init-param> <param-name>propertiesLocation</param-name> <param-value>/WEB-INF/configuration.properties</param-value> </init-param> <init-param> <param-name>applicationConfigLocation</param-name> <param-value>/WEB-INF/application</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> |
Wink provides several APIs for Runtime Registration. The APIs appear in the org.apache.wink.server.utils.RegistrationUtils class.
The most important method is the one that registers an instance
of the javax.ws.rs.core.Application class
static void registerApplication(Application
application, ServletContext servletContext) |
Note
|
Double
Registration Registration is ignored and a warning is printed to the log if the same instance is registered more than once. |
It is sometimes necessary to override the Content-Type response header based on the client user agent. For example, the Firefox browser cannot handle the application/atom+xml media type for Atom content, unless it is defined as a text/xml.
Wink provides a set of predefined Media-Type mappings for use in such cases by supplying the MediaTypeMapper class. Applications may extend or override the MediaTypeMapper class to define additional mappings.
Mappings
Table 3: Predefined Mappings
User Agent |
Content-Type |
Map To |
Mozilla/ |
application/atom+xml |
text/xml |
Mozilla/ |
application/atomsvc+xml |
text/xml |
Mozilla/ |
application/opensearchdescription+xml |
text/xml |
In order to customize these mappings the application should
create an instance of a org.apache.wink.server.internal.MediaTypeMapper
class and set it on the DeploymentConfiguration instance.
Refer to chapter 2, section 2.3.1 for more information on Customizing the Default Deployment Configuration. |
Clients specify the requested media type by setting the Http Accept header. Wink provides an alternate method for specifying the requested media type via use of the “alt” request parameter. This functionality is useful for situations where the client has little affect on the Accept header, for example when requesting a resource using a browser.
A request to “/entry?alt=application/xml” specifies that the requested response media type is application/xml.
Wink provides a shortcut mechanism for specifying the media type of the alt query parameter and provides a predefined set of shortcuts for common media types.
Shortcuts
Table 4: Predefined Shortcuts
Shortcut |
Media
type |
json |
text/javascript |
atom |
application/atom+xml |
xml |
application/xml |
text |
text/plain |
html |
text/html |
csv |
text/csv |
opensearch |
application/opensearchdescription+xml |
The shortcuts table can be customized by overriding the DeploymentConfiguration
class.
Refer to chapter 2, section 2.3 for more information about Deployment Configuration. |
The LinkBuilders interface enables access to two types of links builders, the SystemLinksBuilder and the SingleLinkBuilder. An instance of LinkBuilders is injected into a class field or method parameter using the @Context annotation. Upon creation, the LinkBuilders automatically detects if the target method being invoked is a resource method or a sub-resource method. The “resource” and “subResource” properties of the builder are initialized according to the invoked method type. The link builder interfaces reside in the org.apache.wink.server.utils package.
The JAX-RS specification defines the UriBuilder interface used to construct a URI from a template, but does not specify any mechanism that can automatically generate all resource links.
Wink provides the SystemLinksBuilder for automatic generation of all the alternate links to a resource, one link per every supported media type. For example, this is useful for an application that produces Atom feeds to include in the feed all the alternate representations of the resource.
Wink provides a mechanism for defining if the generated links should be absolute links or relative to a base URI. For example, links embedded in an Atom feed should be as short as possible in order to optimize the payload size.
4.2. The “alt” Query Parameter
Wink supports the special query parameter “alt” that is used to override the value of the request Accept header. When the link builders generate a link that specifies the “type” attribute, then the “alt” query parameter is automatically added to the generated link. This is controlled by setting the wink.addAltParam key of the configuration properties file or by calling the LinksBuilder#addAltParam() method.
Refer to chapter 3, section 3.5 for more information on Configuration Properties. |
The SystemLinksBuilder
interface enables the generation of all, or a subset of, the system links to a
resource or its sub-resources. The links are generated as absolute URIs or as
relative to the base URI according to the SystemLinksBuilder state, request
information or the application configuration.
@Path(“defects/{id}”) public class DefectResource { @GET
@Produces(“application/atom+xml”) public SyndEntry
getAtom() { ... } @GET
@Produces(“application/json”) public JSONObject
getJson() { ... } @GET @Produces(“application/xml”) public Defect
getXml(@Context LinkBuilders linkBuilders) { SystemLinksBuilder builder =
linkBuilders.systemLinksBuilder();
List<SyndLink> systemLinks = builder.build(null); ... } } |
The DefectResource#getXml() method is invoked when a GET request for application/xml is made to /defects/3. The Wink runtime injects an instance of LinkBuilders to the linkBuilder parameter and a new instance of a SystemLinksBuilder is created by invoking the systemLinksBuilder() method.
The call to the build() method of the SystemLinksBuilder
generates three alternate links to the DefectResource and the self link:
·
<link rel=”self”
href=”/defects/3”/>
·
<link rel=”alternate”
type=”application/json” href=”/defects/3”/>
·
<link rel=”alternate”
type=”application/xml” href=”/defects/3”/>
·
<link rel=”alternate”
type=”application/xtom+xml” href=”/defects/3”/>
The SingleLinkBuilder interface enables the generation of
a single link referencing a resource or a sub-resource, allowing the
specification of the ‘rel’ and ‘type’ attributes of the generated
link. The links
are generated as absolute URIs or as relative to the base URI according to the SingleLinkBuilder
state, request information or the application configuration.
4.5. Generating Absolute or Relative Links
The link builders generate
absolute or relative links based on the following algorithm:
1 Use the value that was passed to the relativize() method of the builder.
2 If the relativize() method was not called, then use the value of the “relative-urls” query parameter from the request. The value must be either true or false.
3 If the request does not contain the “relative-urls” query
parameter, then use the value of the wink.defaultUrisRelative key set in
the application configuration properties file. The value must be either true or
false.
Refer to chapter 3, section 3.5 for more information on the Configuration Properties file. |
4 If the configuration key does not exist, then use true.
An Asset is a special entity that is returned by a resource method or is injected into a resource method as an entity parameter. The asset is used for retrieving the actual request entity or response entity.
The purpose of an asset is to act as a container of an entity data model while providing the transformation methods of the data model into data models of other representations.
Asset classes are POJOs, annotated with the @Asset
annotation, that have any number of entity methods.
When an asset instance is returned from a resource method or is
set as the entity on a Response instance, it is used by the Wink runtime to
retrieve the actual response entity by invoking the appropriate entity-producing
method of the asset.
Refer to chapter 5, section 5.3.1
for more information on Entity-Producing Methods. |
When an asset is the entity parameter of a resource method, it is used by the Wink
runtime to set the actual request entity by invoking the appropriate entity-consuming
method of the asset.
Refer to chapter 5, section 5.3.2 for more information on Entity-Consuming Methods. |
A typical application exposes each resource in a number of representations. Some form of data model usually backs the resource, and the application business logic relies on the manipulation of that data model.
The application will most likely expose resource methods allowing the consumption of the data model in more than one representation (for example Atom and XML) and the production of the data model in other representation (for example Atom, XML and JSON).
According to the JAX-RS specification, the optimal method for implementing a resource is one that consumes and produces an application data model and makes use of a different provider for every media type.
For example, if a resource implements methods that consume and produce a ”Defect” bean, then a provider must be implemented for each representation of the “Defect” (Atom, XML and JSON). However, there are times that the transformation of the application data model into a representation requires information that may only be available to the resource but is unavailable to a provider (for example, a connection to the Database).
There are several solutions for dealing with the problem of a provider not having sufficient information to perform application data transformations. The following is a description of two possible solutions:
·
Passing the information as
members on the resource and accessing the resource from the provider via the
UriInfo context.
This solution is only plausible if the resource scope is “per request” and does
not work if the resource is a singleton.
·
Passing the information
from the resource to the provider via the attributes of the HttpServletRequest.
This solution is only plausible when the application is deployed in a JEE
container and is not the optimal solution.
As a result, the selection of the actual provider from the set of potential
providers is non-deterministic, because the selection between them is
undefined.
Note
|
Performance Degradation An additional side effect of provider inflation
is performance degradation. |
The use of an asset solves the problem of passing information between a resource and a provider and reduces the amount of registered providers in the system.
Resource methods can use an asset as a response entity and as a request entity. The Wink runtime applies different lifecycles for each case.
The lifecycle of an asset as a response entity is as follows:
· The application creates and returns the asset from the resource method.
· The appropriate entity-producing method is invoked by the Wink runtime to retrieve the actual response entity.
· The appropriate message body writer as obtained from the Providers#getMessageBodyWriter() method serializes the entity obtained at the previous step.
· The asset is made available for garbage collection.
The lifecycle of an asset as a request entity is as follows:
·
An asset class is
instantiated by the Wink runtime by invoking the asset default constructor. Note
that this implies that the asset class must have a public default constructor.
·
The appropriate message
body reader as obtained from the Providers#getMessageBodyReader() method is
invoked by the Wink runtime to read the request entity.
·
The appropriate
entity-consuming method is invoked on the asset to populate the asset
with the request entity.
·
The asset is injected into the resource method as the entity parameter.
·
The asset is made available
for garbage collection after returning from the resource method.
Asset Entity methods are the public methods of an asset annotated with either @Consumes or @Produces annotation. Annotating a method with both @Consumes and @Produces annotations is not supported and may result in unexpected behavior.
5.3.1. Entity Producing Methods
An Entity Producing Method is a public asset method annotated with the @Produces annotation, designating it to produce the actual response entity. Such methods produce an entity only for the media types declared in the @Produces annotation. Note that under this definition, wildcard (“*/*”) is allowed.
The Wink runtime will not invoke an entity-producing method whose effective value of @Produces does not match the request Accept header
5.3.2. Entity Consuming Methods
An Entity Consuming Method is a public asset method annotated with the @Consumes annotation, designating it to consume the actual request entity for populating the asset. Such methods consume an entity only for the media types declared in the @Consumes annotation. Note that under this definition, wildcard (“*/*”) is allowed.
The Wink runtime will not invoke an entity-consuming method whose effective value of @Consumes does not match the request Content-Type header.
Asset Entity methods support the same parameter types as JAX-RS
specifies for a resource method.
Entity methods may return any
type that is permissible to return from a resource method.
Exceptions thrown from an
entity method are treated as exceptions thrown from a resource method.
The @Produces and @Consumes annotations
are not inherited when an asset sub-class overrides an asset entity method.
Asset sub-classes must re-declare the @Produces and @Consumes annotations for
the overriding method to be an entity method.
Asset classes are handled by
the AssetProvider which is a JAX-RS provider that is capable of
consuming and producing all media types.
Refer
to chapter 3, section 6.3.5
for more information on Asset Providers. |
5.8.1. Request Entity Matching
The following points describe
the process of selecting the asset entity-consuming method to
handle the request entity. This process occurs during the invocation of the
AssetProvider#isReadable() method.
·
Collect all the entity-consuming methods of the asset. These are the public
methods annotated with @Consumes annotation.
·
Sort the collected entity-consuming methods in descending order, where methods
with more specific media types precede methods with less specific media types,
following the rule n/m > n/* > */*.
·
Select the first method that supports the media type of the request entity
body as provided to the AssetProvider#isReadable()
method, and
return true.
·
If no entity-consuming method supports the media type of the request entity
body, return false. The Wink runtime continues searching for a different provider to handle
the asset as a regular entity.
5.8.2. Response Entity Matching
The following points describe the process of selecting an
entity-producing method to produce the actual response entity. The following
process occurs during the invocation of the AssetProvider#isWriteable()method.
·
Collect all the entity-producing methods of the asset. These are the public
methods annotated with @Produces annotation.
·
Sort the collected entity-producing methods in descending order, where methods
with more specific media types precede methods with less specific media types,
following the rule n/m > n/* > */*.
·
Select the first method that supports the media type of the response entity
body as provided to the AssetProvider#isWriteable()method and return true.
·
If no entity-producing method supports the media type of the response
entity body, return false. The Wink runtime continues searching for a
different provider to handle the asset as a regular entity.
The following example illustrates the use of an asset. The “Defect” bean is a JAXB annotated class.
The DefectAsset class is the asset backed by an instance of a
“Defect” bean. The DefectResource class is a resource that is anchored to the
URI path “defects/{id}” within the Wink runtime.
DefectAsset Class
@Asset public class DefectAsset { public Defect defect; public DefectAsset(Defect defect) { this.defect = defect;
} @Produces("application/xml") public Defect getDefect() { return this.defect;
} @Produces("text/html") public String getDefectAsHtml() { String html = ...; return html;
} @Produces("application/atom+xml") public AtomEntry getDefectAsAtom() { AtomEntry entry = ...; return entry;
} @Consumes("application/xml") public void setDefect(Defect defect) { this.defect = defect;
} } |
DefectResource Class
public class DefectResource { @GET public DefectAsset getDefect(@PathParam("id") String id) { return new DefectAsset(defects.get(id)); } @PUT public DefectAsset updateDefect(DefectAsset defectAsset, @PathParam("id") String id) { defects.put(id, defectAsset.getDefect()); return defectAsset; } } |
Scenario Explanation 1
· A client issues an HTTP GET request with a URI=”/defects/1” and Accept Header= “application/xml”
· The Wink runtime analyzes the request and invokes the DefectResource#getDefect() resource method.
· The DefectResource#getDefect() resource method creates an instance of DefectAsset and populates it with defect “1” data.
· The DefectResource#getDefect() resource method returns the DefectAsset instance back to Wink runtime.
· The Wink runtime analyzes the asset and invokes the DefectAsset#getDefect() entity-pro