Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The REST Plugin

Excerpt

provides high level support for the implementation of RESTful resource based web applications

. The REST plugin can cooperate with the Convention Plugin to support a zero configuration approach to declaring your actions and results, but you can always use the REST plugin with XML style configuration if you like.

If you prefer to see a working code example, instead of reading through an explanation, the plugin ships with a struts2-rest-showcase application that demonstrates a simple REST web program.

Features

  • Ruby on Rails REST-style URLs
  • Zero XML config when used with Convention Plugin
  • Built-in serialization and deserialization support for XML and JSON
  • Automatic error handling
  • Type-safe configuration of the HTTP response
  • Automatic conditional GET support

...

This section will walk you through a quick demo.

...

Here are the steps in the sequence that we will follow.

*Setting Up your Project
*Configuring your Project
*Writing your Controllers

Setting Up

Assuming you have a normal Struts 2 application, all you need to do for this REST demo is to add the following two plugins:

...

Just dropping the plugin's into your application may not produce exactly the desired effect. There are a couple of considerations. The first consideration is whether you want to have any non-RESTful URL's coexisting with your RESTful URL's. We'll show two configurations. The first assumes all you want to do is REST. The second assumes you want to keep other non-RESTful URL's alive in the same Struts 2 application.

Note

As with all configuration of Struts 2, we prefer using <constant/> elements in our struts.xml.

REST Only Configuration

Instruct Struts to use the REST action mapper; note, at this point, the REST mapper is the only mapper, so other URL styles won't work:

Code Block
xml
xml
<constant name="struts.mapper.class" value="rest" />

At this point, the REST mapper has replaced the DefaultActionMapper so all incoming URL's will be interpreted as RESTful URL's.

We're relying on the Convention plugin to find our controllers, so we need to configure the convention plugin a bit:

...

Note

Note, you don't have to use the Convention plugin just to use the REST plugin. The actions of your RESTful application can be defined in XML just as easily as by convention. The REST mapper doesn't care how the application came to know about your actions when it maps a URL to an invocation of one of it's methods.

REST and non-RESTful URL's Together Configuration

If you want to keep using some non-RESTful URL's alongside your REST stuff, then you'll have to provide for a configuration that utilizes to mappers.

...

First, you'll need to re-assert the extensions that struts knows about because the rest plugin will have dropped thrown out the action ending in it's own settingsdefault action extension.

Code Block
xml
xml
  <constant name="struts.action.extension" value="xhtml,,xml,json,action"/>

Next, we will configure the PrefixBasedActionMapper, which is part of the core Struts 2 distribution, to have some URL's routed to the Rest mapper and others to the default mapper.

...

Once everything is configured, you need to create the controllers. Controllers are simply actions created with the purpose of handling requests for a give RESTful resource. As we saw in the mapping logic above, various REST URL's will hit different methods on the controller. Traditionally, normal Struts 2 actions expose the execute method as their target method. Here's a sample controller for a orders resource. Note, it this sample doesn't implement all of the possible REST URL to method mappingsmethods that can be hit via the RESTful action mapper's interpretation of URL's.

Code Block
langjava
package org.apache.struts2.rest.example;

public class OrdersController implements ModelDriven<Order> {

    private OrderManager orderManager;
    private String id;
    private Order model;

    // Handles /orders/{id} GET requests
    public HttpHeaders show() {
        model = orderManager.findOrder(id);
        return new DefaultHttpHeaders("show")
            .withETag(model.getUniqueStamp())
            .lastModified(model.getLastModified());
    }

    // Handles /orders/{id} PUT requests
    public String update() {
        orderManager.updateOrder(model);
        return "update";
    }

    // getters and setters
}

...

Also, notice we aren't returning the usual "success" result code in either method. This allows us to use the special features of the Codebehind Plugin to intuitively select the result template to process when this resource is accessed with the .xhtml extension. In this case, we can provide a customized XHTML view of the resource by creating /orders-show.jsp and /orders-update.jsp for the respective methods.

Advanced Topics

The following sections describe some of the non-standard bells and whistles that you might need to utilize for your application's more non-standard requirements.

Custom ContentTypeHandlers

If you need to handle extensions that aren't supported by the default handlers, you can create your own ContentTypeHandler implementation and define it in your struts.xml:

...

Code Block
struts.rest.handlerOverride.xml=myXml

Example

...

Settings

The following settings can be customized. See the developer guide.
For more configuration options see the Convention Plugin Documentation

...