Home > Guides > Plugin Developers Guide > REST Plugin |
The REST Plugin 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, you can download the struts2 sample apps and check out the struts2-rest-showcase
application, a complete WAR file, that demonstrates a simple REST web program.
The main functionality of the REST plugin lies in the interpretation of incoming request URL's according the RESTful rules. In the Struts 2 framework, this 'mapping' of request URL's to Actions is handled by in implementation of the ActionMapper
interface. Out of the box, Struts 2 uses the DefaultActionMapper
to map URL's to Actions via the logic you are probably already familiar with.
The REST plugin provides an alternative implementation, RestActionMapper
, that provides the RESTful logic that maps a URL to a give action class ( aka 'controller' in RESTful terms ) and, more specifically, to the invocation of a method on that controller class. The following section, which comes from the Javadoc for the class, details this logic.
Or, expressed as a table:
HTTP method | URI | Class.method | parameters |
---|---|---|---|
GET | /movie | Movie.index |
|
POST | /movie | Movie.create |
|
PUT | /movie/Thrillers | Movie.update | id="Thrillers" |
DELETE | /movie/Thrillers | Movie.destroy | id="Thrillers" |
GET | /movie/Thrillers | Movie.show | id="Thrillers" |
GET | /movie/Thrillers/edit | Movie.edit | id="Thrillers" |
GET | /movie/new | Movie.editNew |
|
In addition to providing mapping of RESTful URL's to Controller ( Action ) invocations, the REST plugin also provides the ability to produce multiple representations of the resource data. By default, the plugin can return the resource in the following content types:
*HTML
*XML
*JSON
There is nothing configure here, just add the conent type extension to your RESTful URL. The framework will take care of the rest. So, for instance, assuming a Controller called Movies and a movie with the id of superman, the following URL's will all hit the
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
Assuming you have a normal Struts 2 application, all you need to do for this REST demo is to add the following two plugins:
*Struts 2 Rest Plugin
*Struts 2 Convention Plugin
Note, you can download the jars for these plugins from Maven Central
struts.xml
)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.
Instruct Struts to use the REST action mapper:
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:
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 thrown out the default action
extension.
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.
And, again, we're relying on the Convention plugin to find our controllers, so we need to configure the convention plugin a bit:
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, this sample doesn't implement all of the methods that can be hit via the RESTful action mapper's interpretation of URL's.
In this example, the ModelDriven
interface is used to ensure that only my model, the Order object in this case, is returned to the client, otherwise, the whole OrdersController
object would be serialized.
You may wonder why the show()
method returns a HttpHeaders
object and the update()
method returns the expected result code String. The REST Plugin adds support for action methods that return HttpHeaders
objects as a way for the action to have more control over the response. In this example, we wanted to ensure the response included the ETag header and a last modified date so that the information will be cached properly by the client. The HttpHeaders
object is a convenient way to control the response in a type-safe way.
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.
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.
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
:
If the built-in content type handlers don't do what you need, you can override the handling of any extension by providing an alternate handler. First, define your own ContentTypeHandler
and declare with its own alias. For example:
Then, tell the REST Plugin to override the handler for the desired extension with yours. In struts.properties
, it would look like this:
The following settings can be customized. See the developer guide.
For more configuration options see the Convention Plugin Documentation
Setting | Description | Default | Possible Values |
---|---|---|---|
| The alias for the | N/A | Any declared alias for a |
| The default extension to use when none is explicitly specified in the request | | Any extension |
| The HTTP status code to return on validation failure | | Any HTTP status code as an integer |
| Optional parameter to specify namespace for REST services | | eg. /rest |
| Optional parameter, if set to true blocks returning content from any other methods than GET, if set to false, the content can be returned for any kind of method | | eg. put struts.rest.content.restrictToGET = false in struts.properties |
From Struts 2.1.1+