45.3. Fine tuning an application's responses
45.3.1. Basics of building responses
Responseclass 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.
Responseobjects wrap the object representing the entity that is returned to the consumer.
Responseobjects are instantiated using the
ResponseBuilderclass as a factory.
ResponseBuilderclass also has many of the methods used to manipulate the response's metadata. For instance the
ResonseBuilderclass contains the methods for setting HTTP headers and cache control directives.
Relationship between a response and a response builder
Responseclass has a protected constructor, so they cannot be instantiated directly. They are created using the
ResponseBuilderclass enclosed by the
ResponseBuilderclass is a holder for all of the information that will be encapsulated in the response created from it. The
ResponseBuilderclass also has all of the methods responsible for setting HTTP header properties on the message.
Responseclass 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.
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
- Using the static methods of the
Responseclass as shown in Example 45.1, “Getting a response builder using the
Example 45.1. Getting a response builder using the
import 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
ResponseBuilderImplclass. 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 45.2, “Getting a response builder using the
ResponseBuilderImplclass” shows how Example 45.1, “Getting a response builder using the
Responseclass” could be rewritten using the
Example 45.2. Getting a response builder using the
import 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 the
ResponseBuilderreturned from a
Responseclass' method to a
Responseclass see the
ResponseBuilderclass see the
ResponseBuilderImlclass see the
45.3.2. Creating responses for common use cases
Responseclass 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
OKresponse typically contains an entity that corresponds to the request. The
Responseclass has an overloaded
ok()method that sets the response status to
200and 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 of
200and an empty entity body.
Response.ok(java.lang.Object entity)—creates a response with a status of
200, stores the supplied object in the responses entity body, and determines the entities media type by introspecting the object.
200response” shows an example of creating a response with an
Example 45.3. Creating a response with an
import javax.ws.rs.core.Response; import demo.jaxrs.server.Customer; ... Customer customer = new Customer("Jane", 12); return Response.ok(customer).build();
204 No Contentstatus instead of an
200 OKstatus. The
Response.noContent()method will create an appropriate response object.
204status” shows an example of creating a response with an
Example 45.4. Creating a response with a
import javax.ws.rs.core.Response; return Response.noContent().build();
Creating responses for redirection
Responseclass provides methods for handling three of the redirection response statuses.
303 See Other
303 See Otherstatus is useful when the requested resource needs to permanently redirect the consumer to a new resource to process the request.The
seeOther()method creates a response with a
303status and places the new resource URI in the message's
seeOther()method takes a single parameter that specifies the new URI as a
304 Not Modified
304 Not Modifiedstatus 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 previous
GETrequest. It can also be used to signify that a request to modify the resource did not result in the resource being changed.The
notModified()methods creates a response with a
304status and sets the modified date property on the HTTP message. There are three versions of the
307 Temporary Redirect
307 Temporary Redirectstatus 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.The
temporaryRedirect()method creates a response with a
307status and places the new resource URI in the message's
temporaryRedirect()method takes a single parameter that specifies the new URI as a
304status” shows an example of creating a response with an
Example 45.5. Creating a response with a
import javax.ws.rs.core.Response; return Response.notModified().build();
Creating responses to signal errors
Responseclass provides methods to create responses for two basic processing errors:
serverError();—creates a response with a status of
500 Internal Server Error.
notAcceptable(java.util.List<javax.ws.rs.core.Variant> variants);—creates a response with a
406 Not Acceptablestatus and an entity body containing a list of acceptable resource types.
500status” shows an example of creating a response with an
Example 45.6. Creating a response with a
import javax.ws.rs.core.Response; return Response.serverError().build();
45.3.3. Handling more advanced responses
Responseclass 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
Responseclass, you need to use the
ResponseBuilderclasses methods to populate the response before using the
build()method to generate the response object.
ResponseBuilderImplclass to create a response builder instance that can be manipulated directly.
Adding custom headers
header()method takes two parameters:
name—a string specifying the name of the header
value—a Java object containing the data stored in the header
Example 45.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
cookie()method takes one or more cookies. Each cookie is stored in a
javax.ws.rs.core.NewCookieobject. The easiest of the
NewCookieclass' contructors to use takes two parameters:
name—a string specifying the name of the cookie
value—a string specifying the value of the cookie
Example 45.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();
cookie()method with a
nullparameter list erases any cookies already associated with the response.
Setting the response status
Responseclass' helper methods, you can use the
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.Statusobject to specify the response code.
Response.Statusclass is an enumeration enclosed in the
Responseclass. It has entries for most of the defined HTTP response codes.
404 Not Found.
Example 45.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
cacheControl()method allows you to set the cache control headers on the response. The
cacheControl()method takes a
javax.ws.rs.CacheControlobject that specifies the cache control directives for the response.
CacheControlclass 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-agedirective, the setter takes an int value.
no-storecache control directive.
Example 45.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();