此内容没有您所选择的语言版本。
47.3. Fine tuning an application's responses
47.3.1. Basics of building responses
Overview
RESTful services often need more precise control over the response returned to a consumer than is allowed when a resource method returns a plain Java construct. The JAX-RS
Response
class allows a resource method to have some control over the return status sent to the consumer and to specify HTTP message headers and cookies in the response.
Response
objects wrap the object representing the entity that is returned to the consumer. Response
objects are instantiated using the ResponseBuilder
class as a factory.
The
ResponseBuilder
class also has many of the methods used to manipulate the response's metadata. For instance the ResonseBuilder
class contains the methods for setting HTTP headers and cache control directives.
Relationship between a response and a response builder
The
Response
class has a protected constructor, so they cannot be instantiated directly. They are created using the ResponseBuilder
class enclosed by the Response
class. The ResponseBuilder
class is a holder for all of the information that will be encapsulated in the response created from it. The ResponseBuilder
class also has all of the methods responsible for setting HTTP header properties on the message.
The
Response
class does provide some methods that ease setting the proper response code and wrapping the entity. There are methods for each of the common response status codes. The methods corresponding to status that include an entity body, or required metadata, include versions that allow for directly setting the information into the associated response builder.
The
ResponseBuilder
class' build()
method returns a response object containing the information stored in the response builder at the time the method is invoked. After the response object is returned, the response builder is returned to a clean state.
Getting a response builder
There are two ways to get a response builder:
- Using the static methods of the
Response
class as shown in Example 47.1, “Getting a response builder using theResponse
class”.Example 47.1. Getting a response builder using the
Response
classimport javax.ws.rs.core.Response; Response r = Response.ok().build();
When getting a response builder this way you do not get access to an instance you can manipulate in multiple steps. You must string all of the actions into a single method call. - Using the Apache CXF specific
ResponseBuilderImpl
class. This class allows you to work directly with a response builder. However, it requires that you manually set all of the response builders information manually.Example 47.2, “Getting a response builder using theResponseBuilderImpl
class” shows how Example 47.1, “Getting a response builder using theResponse
class” could be rewritten using theResponseBuilderImpl
class.Example 47.2. Getting a response builder using the
ResponseBuilderImpl
classimport javax.ws.rs.core.Response; import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl; ResponseBuilderImpl builder = new ResponseBuilderImpl(); builder.status(200); Response r = builder.build();
NoteYou could also simply assign theResponseBuilder
returned from aResponse
class' method to aResponseBuilderImpl
object.
More information
For more information about the
Response
class see the Response
class' Javadoc.
For more information about the
ResponseBuilder
class see the ResponseBuilder
class' Javadoc.
For more information on the Apache CXF
ResponseBuilderIml
class see the ResponseBuilderImpl
Javadoc.
47.3.2. Creating responses for common use cases
Overview
The
Response
class provides shortcut methods for handling the more common responses that a RESTful service will need. These methods handle setting the proper headers using either provided values or default values. They also handle populating the entity body when appropriate.
Creating responses for successful requests
When a request is successfully processed the application needs to send a response to acknowledge that the request has been fulfilled. That response may contain an entity.
The most common response when successfully completing a response is
OK
. An OK
response typically contains an entity that corresponds to the request. The Response
class has an overloaded ok()
method that sets the response status to 200
and adds a supplied entity to the enclosed response builder. There are five versions of the ok()
method. The most commonly used variant are:
Response.ok()
—creates a response with a status of200
and an empty entity body.Response.ok(java.lang.Object entity)
—creates a response with a status of200
, stores the supplied object in the responses entity body, and determines the entities media type by introspecting the object.
Example 47.3, “Creating a response with an
200
response” shows an example of creating a response with an OK
status.
Example 47.3. Creating a response with an 200
response
import javax.ws.rs.core.Response; import demo.jaxrs.server.Customer; ... Customer customer = new Customer("Jane", 12); return Response.ok(customer).build();
For cases where the requester is not expecting an entity body, it may be more appropriate to send a
204 No Content
status instead of an 200 OK
status. The Response.noContent()
method will create an appropriate response object.
Example 47.4, “Creating a response with a
204
status” shows an example of creating a response with an 204
status.
Example 47.4. Creating a response with a 204
status
import javax.ws.rs.core.Response; return Response.noContent().build();
Creating responses for redirection
The
Response
class provides methods for handling three of the redirection response statuses.
303 See Other
- The
303 See Other
status is useful when the requested resource needs to permanently redirect the consumer to a new resource to process the request.TheResponse
classesseeOther()
method creates a response with a303
status and places the new resource URI in the message'sLocation
field. TheseeOther()
method takes a single parameter that specifies the new URI as ajava.net.URI
object. 304 Not Modified
- The
304 Not Modified
status can be used for different things depending on the nature of the request. It can be used to signify that the requested resource has not changed since a previousGET
request. It can also be used to signify that a request to modify the resource did not result in the resource being changed.TheResponse
classesnotModified()
methods creates a response with a304
status and sets the modified date property on the HTTP message. There are three versions of thenotModified()
method:notModified();
notModified(javax.ws.rs.core.Entity tag);
notModified(java.lang.String tag);
307 Temporary Redirect
- The
307 Temporary Redirect
status is useful when the requested resource needs to direct the consumer to a new resource, but wants the consumer to continue using this resource to handle future requests.TheResponse
classestemporaryRedirect()
method creates a response with a307
status and places the new resource URI in the message'sLocation
field. ThetemporaryRedirect()
method takes a single parameter that specifies the new URI as ajava.net.URI
object.
Example 47.5, “Creating a response with a
304
status” shows an example of creating a response with an 304
status.
Example 47.5. Creating a response with a 304
status
import javax.ws.rs.core.Response; return Response.notModified().build();
Creating responses to signal errors
The
Response
class provides methods to create responses for two basic processing errors:
serverError();
—creates a response with a status of500 Internal Server Error
.notAcceptable(java.util.List<javax.ws.rs.core.Variant> variants);
—creates a response with a406 Not Acceptable
status and an entity body containing a list of acceptable resource types.
Example 47.6, “Creating a response with a
500
status” shows an example of creating a response with an 500
status.
Example 47.6. Creating a response with a 500
status
import javax.ws.rs.core.Response; return Response.serverError().build();
47.3.3. Handling more advanced responses
Overview
The
Response
class methods provide short cuts for creating responses for common cases. When you need to address more complicated cases such as specifying cache control directives, adding custom HTTP headers, or sending a status not handled by the Response
class, you need to use the ResponseBuilder
classes methods to populate the response before using the build()
method to generate the response object.
Tip
As discussed in the section called “Getting a response builder”, you can use the Apache CXF
ResponseBuilderImpl
class to create a response builder instance that can be manipulated directly.
Adding custom headers
Custom headers are added to a response using the
ResponseBuilder
class' header()
method. The header()
method takes two parameters:
name
—a string specifying the name of the headervalue
—a Java object containing the data stored in the header
You can set multiple headers on the message by calling the
header()
method repeatedly.
Example 47.7, “Adding a header to a response” shows code for adding a header to a response.
Example 47.7. Adding a header to a response
import javax.ws.rs.core.Response; import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl; ResponseBuilderImpl builder = new ResponseBuilderImpl(); builder.header("username", "joe"); Response r = builder.build();
Adding a cookie
Custom headers are added to a response using the
ResponseBuilder
class' cookie()
method. The cookie()
method takes one or more cookies. Each cookie is stored in a javax.ws.rs.core.NewCookie
object. The easiest of the NewCookie
class' contructors to use takes two parameters:
name
—a string specifying the name of the cookievalue
—a string specifying the value of the cookie
You can set multiple cookies by calling the
cookie()
method repeatedly.
Example 47.8, “Adding a cookie to a response” shows code for adding a cookie to a response.
Example 47.8. Adding a cookie to a response
import javax.ws.rs.core.Response; import javax.ws.rs.core.NewCookie; NewCookie cookie = new NewCookie("username", "joe"); Response r = Response.ok().cookie(cookie).build();
Warning
Calling the
cookie()
method with a null
parameter list erases any cookies already associated with the response.
Setting the response status
When you want to return a status other than one of the statuses supported by the
Response
class' helper methods, you can use the ResponseBuilder
class' status()
method to set the response's status code. The status()
method has two variants. One takes an int that specifies the response code. The other takes a Response.Status
object to specify the response code.
The
Response.Status
class is an enumeration enclosed in the Response
class. It has entries for most of the defined HTTP response codes.
Example 47.9, “Adding a header to a response” shows code for setting the response status to
404 Not Found
.
Example 47.9. Adding a header to a response
import javax.ws.rs.core.Response; import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl; ResponseBuilderImpl builder = new ResponseBuilderImpl(); builder.status(404); Response r = builder.build();
Setting cache control directives
The
ResponseBuilder
class' cacheControl()
method allows you to set the cache control headers on the response. The cacheControl()
method takes a javax.ws.rs.CacheControl
object that specifies the cache control directives for the response.
The
CacheControl
class has methods that correspond to all of the cache control directives supported by the HTTP specification. Where the directive is a simple on or off value the setter method takes a boolean value. Where the directive requires a numeric value, such as the max-age
directive, the setter takes an int value.
Example 47.10, “Adding a header to a response” shows code for setting the
no-store
cache control directive.
Example 47.10. Adding a header to a response
import javax.ws.rs.core.Response; import javax.ws.rs.core.CacheControl; import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl; CacheControl cache = new CacheControl(); cache.setNoCache(true); ResponseBuilderImpl builder = new ResponseBuilderImpl(); builder.cacheControl(cache); Response r = builder.build();