http://www.developer.com/java/web/article.php/3875781/Leveraging-the-Restlet-Routing-System-for-Your-Java-Web-Services.htm
As Restlet applications have multiple important purposes, it is essential to understand how they are structured and then used at runtime by Restlet projects. In Figure 1, we illustrate their overall design into three concentric layers, from the most generic and reusable on the edge to the most specific in the center. An application can handle both inbound server calls and outbound client calls, which are depicted using arrows. An inbound call first goes though a service filtering layer, which is common to all resources contained in the application. This layer can handle things such as automatic decoding of compressed representations or support for partial representations. Then, the call goes through a user routing layer, where you will be able to do your own filtering, for example, for authentication purpose and to route the request to its target resource, typically based on its URI. Finally, the call can reach the resource handling layer, where a target resource will handle the request and reply with a response that will return to the original client, following the same path. This request processing flow that we summarized is followed by a single Java thread in charge of the given call. In addition, client calls can be initiated by applications, typically, while handling server calls inside server resources, by creating client resources. A client resource sends a request through the upper layers, before it reaches the target resource (typically on a remote host), and finally comes back with a response. The user routing layer will have a chance to filter or dispatch the request, for example, to handle automatic authentication, while the upper service filtering layer will be able to provide services such as automatic decompression of representations received in responses. The user routing layer can be pretty limited, providing just a simple Restlet subclass that traces incoming calls. How can you build a filter that blocks some IP addresses or route calls to target server resource based on their URI? In this article we will introduce you to the Restlet routing system and answer the above questions. We will especially present Restlet filters and routers which are two key elements of this routing system, the first one facilitating the pre-processing and post-processing of calls, the second one allowing the dispatching of calls to one of the several target routes available, typically based on the target URI of the routed call. On the server side, after receiving calls, or on the client side, before sending calls, it is common to systematically apply some behavior that doesn't differ much based on the target resource URI of the call. The common name for such processing elements is 'filter.' Naturally, the Restlet Framework offers an abstract In Figure 2, we illustrate three concurrent calls (A, B, and C) processed by the same Like all Restlet subclasses, Let's now look at a concrete example in Listing 1 that provides a blocking filter based on IP addresses. You can see that we used a special thread-safe implementation of the In order to test this filter, we need to update our application, especially the You can see in Listing 3 how the filter is returned as the new inbound root and attached to a In order to test our filter, you can launch the updated application and point your browser to the http://localhost:8182/test/abcd URI. It should return the same result as with the previous listings. Now, uncomment the second line in the method above and restart your application. If you refresh your browser page, you should see this time the "Your IP address was blocked" message indicating that our filter worked! In addition to the base Then, we find two security related filters, the Note that those filters should only be used if their behavior is useful for a set of target resources; otherwise, it is better to add this logic inside your resources directly. Finally, there is a fifth filter called So far, we illustrated how inbound or outbound calls could be filtered in order to apply pre-processing or post-processing. What is missing from this puzzle is a way to direct calls to target resources, to route them based on properties like the target URI. This is the purpose of the In Figure 4, we illustrated how three calls (A, B, and C), supported by three concurrent threads, enter a The actual class used is In order to illustrate what we just learned, let's run a simple example based on the Tracer and Blocker filters that we previously developed and attach them to a Router instance (see Listing 4). In this scenario, we create two filters, one One of the nice features of the Router and, especially, the In some cases, it is necessary to customize the way the URI matching happens. The Another property is Also, when the router evaluates each route, it is possible to define when it considers a given route as the one to select and pass the call to. This is the purpose of the This opens the way for many interesting usages, such as writing a load-balancer of calls to several instances of a back-end web service. But there is more: in addition to First, a In this article, we learned how Restlet applications are structured in three concentric layers and the detailed design of each layer. In addition, we explored the Restlet routing system, which allows the pre-processing and post-processing of both inbound and outbound calls with the
Leveraging the Restlet Routing System for Your Java Web Services
April 9, 2010
This article is taken from the book "Restlet in Action" (Manning Publications; ISBN: 9781935182344), written by Jerome Louvel and Thierry Boileau. The authors provide an overview of Restlet applications and then present Restlet filters and routers, the two key elements of the Restlet routing system. They show how filters facilitate the pre-processing and post-processing of calls, and how the routers allow the dispatching of calls to one of the several target routes available. 
Figure 1. Restlet applications are structured into three concentric layers, processing inbound and outbound calls in logical steps.Inbound and Outbound Calls in Restlet Applications
The Restlet Routing System
Pre-processing and Post-processing Calls with a Filter
org.restlet.routing.Filter class, which is a subclass of org.restlet.Restlet.Restlet subclasses are multi-threaded
It is important to mention that Restlet subclasses must support concurrent calls and be fully thread-safe. Writing code that behaves properly when executed by several threads (one for each call) is not easy and we highly recommend that you read the "Java Concurrency in Practice" for more on this topic.Filter instance. Each thread supports a call (a request and response couple) and attempts to traverse the filter to reach the next Restlet. Sometimes, the call will get blocked by the filter and the thread will return immediately without going to the next Restlet. Call B is stopped by the filter as illustrated by the "stop" sign. 
Figure 2. Filter handling three concurrent calls, passing two of them to the next Restlet and blocking the third oneFilter's entry point is the final handle(Request, Response) method declared in the Uniform interface. This method works in three steps:
beforeHandle(Request, Response) method which lets the filter pre-process the call.doHandle(Request, Response) method. If no Restlet is attached, then a "server internal error" (HTTP status 500) is set on the response.afterHandle(Request, Response) method is invoked, giving the filter a chance to post-process the call. Post-processing typically is based on the response received, for example, to compress the representation returned for an HTTP GET method.Set<String> interface to store the list of blocked IP addresses.public class Blocker extends org.restlet.routing.Filter {
private final Set<String> blockedAddresses; #A
public Blocker(Context context) {
super(context);
this.blockedAddresses = new CopyOnWriteArraySet<String>();
}
@Override
protected int beforeHandle(Request request, Response response) { #B
int result = STOP;
if (getBlockedAddresses()
.contains(request.getClientInfo().getAddress())) {
response.setStatus(Status.CLIENT_ERROR_FORBIDDEN,
"Your IP address was blocked");
} else {
result = CONTINUE;
}
return result;
}
public Set<String> getBlockedAddresses() {
return blockedAddresses;
}
}
#A The list of blocked IP addresses.
#B The pre-processing method comparing the client IP address with the list of blocked addresses.createInboundRoot() method to return an instance of the Blocker filter instead of the Tracer class which contains the same logic as in Listing 2, but packaged as a separate class extending Restlet.import org.restlet.Application;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.Server;
import org.restlet.data.MediaType;
import org.restlet.data.Protocol;
public class MailServerApplication extends Application {
public static void main(String[] args) throws Exception { #A
Server mailServer = new Server(Protocol.HTTP, 8182);
mailServer.setNext(new MailServerApplication());
mailServer.start();
}
@Override
public Restlet createInboundRoot() { #B
return new Restlet() {
@Override
public void handle(Request request, Response response) {
String entity = "Method : " + request.getMethod()
+ "\nResource URI : "
+ request.getResourceRef()
+ "\nIP address : "
+ request.getClientInfo().getAddress()
+ "\nAgent name : "
+ request.getClientInfo().getAgentName()
+ "\nAgent version: "
+ request.getClientInfo().getAgentVersion();
response.setEntity(entity, MediaType.TEXT_PLAIN);
}
};
}
}
#A Launches the application with an HTTP server.
#B Creates a root Restlet to trace requests.Tracer instance using the setNext(Restlet) method.@Override
public Restlet createInboundRoot() {
Blocker blocker = new Blocker(getContext());
// blocker.getBlockedAddresses().add("127.0.0.1");
blocker.setNext(new Tracer(getContext()));
return blocker;
}Overview of the Available Filters
Filter class, the Restlet API comes with several filters ready to use, as illustrated in the Figure 3. First, we have the Extractor providing a way to extract values from request cookies, query parameters or posted forms, and to store them as request attributes for easier processing down the road, for example, using the Validator filter, which can check for the presence of attributes with a given name and the format of their string value.Authenticator, to verify the credentials given by a user or to ask him to provide them, and the Authorizer, to enforce access policies.
Figure 3. Class diagram showing some common org.restlet.routing.Filter subclassesTemplateRoute that isn't displayed in the figure because it is rarely used directly. Instead, you generally leverage it via the Router class, which is our next topic.Dispatching Calls Based on URIs with a Router
org.restlet.routing.Router class, a direct subclass of Restlet, which is composed of a list of routes and a set of properties that define how the routing of an incoming call to one of the routes actually happens. Of course, like all Restlet subclasses, a Router must be thread safe to support the routing of several concurrent calls.Router instance to end into one of the three attached routes (1, 2, and 3) but not necessarily at the same time. In this example, call A reaches route 1, while calls B and C reach route 2. If you pay attention to the form of the figure used for routes, you will recognize the cylinder that we used for filters.TemplateRoute in the same package, which defines the next Restlet like all filters, but also a score(Request, Response) method. As its name implies, this method computes an affinity score based on the matching of the URI of the target resource (contained in the Request#resourceRef property) with a given URI template. An example of URI template is http://localhost:8182/accounts/{accountId}.
Figure 4. Router handling three concurrent calls and dispatching them to attached routes@@Override
public Restlet createInboundRoot() {
Tracer tracer = new Tracer(getContext());
Blocker blocker = new Blocker(getContext());
blocker.getBlockedAddresses().add("127.0.0.1");
blocker.setNext(tracer);
Router router = new Router(getContext());
router.attach("http://localhost:8182/", tracer);
router.attach("http://localhost:8182/accounts/", tracer);
router.attach("http://localhost:8182/accounts/{accountId}", blocker);
return router;
}Tracer instance and one Blocker instance pointing to the tracer. Then, based on URI templates, we define which filter will be invoked when the request's target URI matches a given route. Note that TemplateRoute instance doesn't need to be explicitly created; instead, we can rely on the handy attach(String, Restlet) method. Let's start our updated application and test a few URIs in our browser, as detailed in Table 1.
URI retrieved
Result observed
http://localhost:8182/
Trace results are displayed
http://localhost:8182/?param=value
Trace results are displayed, including the query string
http://localhost:8182/123
Error: "The server has not found anything matching the request URI"
http://localhost:8182/accounts/
Trace results are displayed
http://localhost:8182/accounts/123
Error: "Your IP address was blocked"
TemplateRoute is that the URI variables are automatically extracted and stored in the request's attributes map. In our last example URI, the string 123 corresponding to the {accountId} variable in the URI template http://localhost:8182/accounts/{accountId} will be stored in an attribute named accountId. This will be very convenient when we actually handle the call in a ServerResource subclass to retrieve the underlying domain object from the database.Router class has a full range of options to take care of this need, such as a defaultMatchingMode property indicating if only the beginning of the URI must match (see the org.restlet.routing.Template#STARTS_WITH constant) or if all the URI must match (see the EQUALS constant). The latter case is the default mode since Restlet 2.0, so be careful if you upgrade from the previous version.defaultMatchQuery, which indicates if the query string at the end of target URIs (the characters after the optional "?" character) should be considered during matching. By default, its value is false as the order of query parameters is rarely enforceable. Restlet developers tend to prefer handling them inside the resource classes. Keep also in mind that it is possible to customize the characters that are matched by the URI template variables leveraging the Template and Variable classes.routingMode property, which can have one of the following values (those constants are defined in the Router class):
Restlet instances, you can also attach server resource classes directly to a Router using an attach(String, Class) method, as illustrated in Figure 5. But what happen exactly inside this method?
Figure 5. Router dispatching concurrent calls to three target server resourcesTemplateRoute instance is created and added to the list of routes of the router, and then a special Restlet subclass called org.restlet.resource.Finder is attached to the route. This class will store the class name of the target resource and create a new instance of it for each incoming call. This is very similar to the factory design pattern. With the introduction of the Finder class, we see how the transition from the user routing layer to the resource handling layer will happen.Summary
Filter class and the dispatching of calls to attached routes by the Router class.About the Author
Jerome Louvel is the co-founder of Noelios Technologies and the creator of Restlet.
Thierry Boileau is the co-founder of Noelios Technologies and has been a core developer of the Restlet Framework since 2006.