Custom Annotated Validator in REST Service

@Path(“/”) class MyResourceClass {

 @POST
 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Built-in
public void registerUser(
 @NotNull @FormParam(“firstName”) String fn,
 @NotNull @FormParam(“lastName”) String ln,
Custom
@Email @FormParam(“email”) String em) { … } }

User defined Constraints
@Target({ METHOD, FIELD, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = EmailValidator.class)
public @interface Email { … } class EmailValidator implements ConstraintValidator {
 public void initialize(Email email) { … }
 public boolean isValid(String value, ConstraintValidatorContext context) { // Check value is e-mail address … } }

Creating a REST root resource class

The REST root resource class. This is the Java method on your server that accepts and handles a RESTful message. Back in Eclipse, we’re going to create and define the REST class now.

You might notice the options for a RESTful web service from pattern in the right click menu. This option generates a file with a set of methods to deal with each of the HTTP commands and the generic structure. In the future, this can save some time when creating a REST class, but for the purposes of this blog, we’ll just create the default class. So give it a name, and click Finish. The first thing we need to do in this new file is to specify the path. This will be the final part of the URI that is used to reference the RESTful class. The path is defined as an annotation on the class of the form @Path()value equals and then the name in quotation marks.

You will have to import the appropriate file to the path annotation so that Java knows what you’re talking about and how to interpret it. Next, we need a constructor. Nothing fancy here, just create an empty void method, with the same name as the class. With the setup out of the way, we can move on to the four main methods, get, put, post, and delete. These methods will handle the corresponding ACDP commands in the way you define. With the get method, define a new public object get, and parentheses. And then add a simple return statement such as return Hello World.

Now we need to do two things. First, we need to associate this method with the HTTP get method. And second, we need to renotify the requester that this will produce an XML file. Associating the get method is easy. Just add an @GET annotation for the method. As before, you’ll have to import this so Java knows what you’re talking about. We can’t notify the requester that this will produce an XML file the normal way by changing the method return type because Java doesn’t support an XML file as a return type.

Instead, add another annotation with the form @Produces, then in parenthesis text/xml. Go ahead and import this annotation. Make sure you import it from Javax.ws.rs, the same as the other annotations and this annotation will be read by the requester and will notify them that this method returns an XML file. The file that we import to make this work contains all of the necessary information to go from the Java method to the HTTP request.

A PUT method works in much the same way. This function is going to take in an XML file and return nothing. So the method would be formatted as public void put String content. Then the annotations are@PUT and @Consumes, and then text/xml in quotation marks. As before, we import these. And these tell the requester that the put method must provide an XML file on which to operate.

Post and delete both have the same format as put, because they both take in an XML file and then do something with it. Once you have support for these four methods, you’ve created the structure for a RESTful resource class. The implementation of those methods and their supporting methods will define what the class actually does, but this is specific to your database and to your preferred functionality. The coding is going to be standard Java code, using the provided inputs and outputs.

What is REST ?

REST is acronym for Representational State Transfer.
REST primary goals:
  • Scalability–which means REST based system should work well with many clients and many transactions.
  • Generality of Interfaces– adaptible to any business process.
  • Independent depolyment of components–just like SAOP, Client and Server in a REST based conversation don’t need to using same operating system or programming language.

 An REST based service can depend on intermediary components to do latency,security and encapsulate legacy systems.

REST Request Messages:

A RESTful request is typically in form of Uniform Resource Identifiers(URI)
Structure of URI depends on specific service
Requests can also include parameters in body of request as XML,JSON or other format

maps.googleapis.com/maps/api/geocode/xml?address=New%20York&sensor=false

maps.googleapis.com -> Domain Root
maps/api/geocode -> Resource Root

To change the response to json
maps.googleapis.com/maps/api/geocode/json?address=New%20York&sensor=false

 RESTful Methods:

A RESTful webservice is written using Http methods

There are four main http methods,they usually have the same syntax.
GET
POST
PUT
DELETE

GET /users/name HTTP/1.1
Host:servername
Accept:text/xml–This line specifies the data you are looking for.

GET /users/adduser?username=name HTTP/1.1 is valid.
 it is friend upon and retrieve a username and add a new user in a single request.
The problem is that GET request are not supposed to be used for this purpose.GET,PUT and DELETE method are supposed to be Idempotent.

request should not cause any additional change with they run more than once with the same parameter.

for instance:If you delete something and try to delete it again,r.nothing will happen because there is nothing to delete.
same principal
This Idem-potency is important for the program structure,you dont have to check each and every loop.
Only the post method which creates a resource on the server is not Idempotent.
So if you want to add a user and retrieve user,The best way to accomplish is would be in two separate commands.Post method is to add the user and GET method to retrieve the user.

POST /users/name HTTP/1.1
Host:servername
Content-Type:text/xmlag>

 
 

HTTP Caching in Java with JAX-RS

Table of Contents

HTTP caching is an easy and oft-ignored option to speed up web applications. It’s standardized and well implemented in all modern browsers and results in a lower latency app and improved responsiveness.

Please see the increasing application performance with HTTP cache headers article for a more thorough discussion of HTTP cache headers.

Java offers a wide variety of frameworks to build a REST-API. This article focuses on implementing HTTP caching with the JAX-RS framework.

If you have questions about Java on Heroku, consider discussing them in the Java on Heroku forums.

Time-based cache headers

In HTTP 1.1 the Cache-Control header specifies the resource caching behavior as well as the max age the resource can be cached. As an example, this response would be cached for one day:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private, max-age=86400
Last-Modified: Thu, 07 Feb 2013 11:56 EST

Here is a list of all the available Cache-Control tokens and their meaning:

  • private only clients (mostly the browser) and no one else in the chain (like a proxy) should cache this
  • public any entity in the chain can cache this
  • no-cache should not be cached anyway
  • no-store can be cached but should not be stored on disk (most browsers will hold the resources in memory until they will be quit)
  • no-transform the resource should not be modified (for example shrink image by proxy)
  • max-age how long the resource is valid (measured in seconds)
  • s-maxage same like max-age but this value is just for non clients

Setting the Cache-Control header

In a JAX-RS method a Response object can be returned. The content will be auto transformed according to the specified MIME-Type (this is called JAX-RS Content Negotiation). The Cache-Control header can also be set on the Response object by using the CacheControl class. Methods are provided for all of the available Cache-Control header tokens.

@Path("/book/{id}")
@GET
public Response getBook(@PathParam("id") long id){

        Book myBook = getBookFromDB(id);

        CacheControl cc = new CacheControl();
        cc.setMaxAge(86400);
        cc.setPrivate(true);

        ResponseBuilder builder = Response.ok(myBook);
        builder.cacheControl(cc);
        return builder.build();
}

Alt text

Conditional cache headers

Conditional requests are those where the browser can ask the server if it has an updated copy of the resource. The browser will send one or both of the ETag and If-Modified-Since headers about the cached resource it holds. The server can then determine whether updated content should be returned or the browser’s copy is the most recent.

Making a conditional GET

In JAX-RS the Request object has a method to check wether the data based on the date or the etag from the client was modified. The ETag value should be a unique hash of the resource and requires knowledge of internal business logic to construct. One possibility is to use the HashCode of a object as the etag.

@Path("/book/{id}")
@GET
public Response getBook(@PathParam("id") long id, @Context Request request){

        Book myBook = getBookFromDB(id);
        CacheControl cc = new CacheControl();
        cc.setMaxAge(86400);

        EntityTag etag = new EntityTag(Integer.toString(myBook.hashCode()));
        ResponseBuilder builder = request.evaluatePreconditions(etag);

        // cached resource did change -> serve updated content
        if(builder == null){
                builder = Response.ok(myBook);
                builder.tag(etag);
        }

        builder.cacheControl(cc);
        return builder.build();
}

A ResponseBuilder is automatically constructed by calling evaluatePreconditions on the request. If the builder is null, the resource is out of date and needs to be sent back in the response. Otherwise, the preconditions indicate that the client has the latest version of the resource and the 304 Not Modified status code will be automatically assigned.

Alt text

Alt text

Making a conditional PUT

Resource updates can also be conditional. The client would receive 412 Precondition Failed if the ETag send by the client does not match the one on the server. Otherwise the update could be made and a 200 OK with the updated entity or a 204 No Content would be send back.

@Path("/book/{id}")
@PUT
@Consumes("application/json")
public Response getBook(@PathParam("id") long id, @Context Request request, Book updatedBook){

        Book myBook = getBookFromDB(id);
        EntityTag etag = new EntityTag(Integer.toString(myBook.hashCode()));

        ResponseBuilder builder = request.evaluatePreconditions(etag);

        // client is not up to date (send back 412)
        if(builder != null){
                return builder.build();
        }

        updateBookInDB(updatedBook);

        builder = Response.noContent();
        return builder.build();
}

More About Http Headers with JAX-RS

Mapping of a particular URI(“/customers”) to a service(CustomerService) that returns some resource is straightforward using the @Path annotation.

@Path("/customers")
public class CustomerService {
    @GET
    public Customers getCustomers() {
        ......
    }
    @GET
    @Path("/{id}")
    public Customer getCustomer(@PathParam("id") String id) {
        ......
    }
}

For this service we can assume that the returned list of customers exposes only basic attributes and more details is returned using the second method which uses the customer id as the key. Something like this:

GET http://foobar.com/api/customers
 
<customers>
    <customer id="1005">John Doe</customer>
    <customer id="1006">Jane Doe</customer>
    ...
</customers>
    
GET http://foobar.com/api/customers/1005
 
<customer id="1005">
    <first-name>John</first-name>
    <last-name>Doe</last-name>
    ...
</customer>

How does a client of this service know how to get from list of customers to given customer? A trivial approach would be to expect the client to compute the proper URI. But wouldn’t it be better to have the services provide full URIs in the response that can be used directly? This way the client would be more decoupled from the service itself (which may change URI format over time). A client could be provided the following on re