javax.ws.rs.core.Response Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.ws.rs.core;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.net.URI;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.RuntimeDelegate;
/**
* Defines the contract between a returned instance and the runtime when
* an application needs to provide meta-data to the runtime.
*
* An application class should not extend this class directly. {@code Response} class is
* reserved for an extension by a JAX-RS implementation providers. An application should use one
* of the static methods to create a {@code Response} instance using a ResponseBuilder.
*
*
* Several methods have parameters of type URI, {@link UriBuilder} provides
* convenient methods to create such values as does {@link URI#create(java.lang.String)}.
*
*
* @author Paul Sandoz
* @author Marc Hadley
* @author Marek Potociar
* @see Response.ResponseBuilder
* @since 1.0
*/
public abstract class Response {
/**
* Protected constructor, use one of the static methods to obtain a
* {@link ResponseBuilder} instance and obtain a Response from that.
*/
protected Response() {
}
/**
* Get the status code associated with the response.
*
* @return the response status code.
*/
public abstract int getStatus();
/**
* Get the complete status information associated with the response.
*
* @return the response status information. The returned value is never
* {@code null}.
* @since 2.0
*/
public abstract StatusType getStatusInfo();
/**
* Get the message entity Java instance. Returns {@code null} if the message
* does not contain an entity body.
*
* If the entity is represented by an un-consumed {@link InputStream input stream}
* the method will return the input stream.
*
*
* @return the message entity or {@code null} if message does not contain an
* entity body.
* @throws IllegalStateException if the entity was previously fully consumed
* as an {@link InputStream input stream}, or
* if the response has been {@link #close() closed}.
*/
public abstract Object getEntity();
/**
* Read the message entity input stream as an instance of specified Java type
* using a {@link javax.ws.rs.ext.MessageBodyReader} that supports mapping the
* message entity stream onto the requested type.
*
* Method throws an {@link ProcessingException} if the content of the
* message cannot be mapped to an entity of the requested type and
* {@link IllegalStateException} in case the entity is not backed by an input
* stream or if the original entity input stream has already been consumed
* without {@link #bufferEntity() buffering} the entity data prior consuming.
*
*
* If the message does not contain an entity body {@code null} is returned.
* A non-null message instance returned from this method will be cached for
* subsequent retrievals via {@link #getEntity()}. Unless the supplied entity
* type is an {@link java.io.InputStream input stream}, this method automatically
* {@link #close() closes} the an unconsumed original response entity data stream
* if open. In case the entity data has been buffered, the buffer will be reset
* prior consuming the buffered data to enable subsequent invocations of
* {@code readEntity(...)} methods on this response.
*
*
* @param entity instance Java type.
* @param entityType the type of entity.
* @return the message entity; for a zero-length response entities returns {@code null}
* or a corresponding Java object that represents zero-length data.
* @throws ProcessingException if the content of the message cannot be
* mapped to an entity of the requested type.
* @throws IllegalStateException if the entity is not backed by an input stream,
* the response has been {@link #close() closed} already,
* or if the entity input stream has been fully consumed already and has
* not been buffered prior consuming.
* @see javax.ws.rs.ext.MessageBodyReader
* @since 2.0
*/
public abstract T readEntity(Class entityType);
/**
* Read the message entity input stream as an instance of specified Java type
* using a {@link javax.ws.rs.ext.MessageBodyReader} that supports mapping the
* message entity stream onto the requested type.
*
* Method throws an {@link ProcessingException} if the content of the
* message cannot be mapped to an entity of the requested type and
* {@link IllegalStateException} in case the entity is not backed by an input
* stream or if the original entity input stream has already been consumed
* without {@link #bufferEntity() buffering} the entity data prior consuming.
*
*
* If the message does not contain an entity body {@code null} is returned.
* A non-null message instance returned from this method will be cached for
* subsequent retrievals via {@link #getEntity()}. Unless the supplied entity
* type is an {@link java.io.InputStream input stream}, this method automatically
* {@link #close() closes} the an unconsumed original response entity data stream
* if open. In case the entity data has been buffered, the buffer will be reset
* prior consuming the buffered data to enable subsequent invocations of
* {@code readEntity(...)} methods on this response.
*
*
* @param entity instance Java type.
* @param entityType the type of entity; may be generic.
* @return the message entity; for a zero-length response entities returns {@code null}
* or a corresponding Java object that represents zero-length data.
* @throws ProcessingException if the content of the message cannot be
* mapped to an entity of the requested type.
* @throws IllegalStateException if the entity is not backed by an input stream,
* the response has been {@link #close() closed} already,
* or if the entity input stream has been fully consumed already and has
* not been buffered prior consuming.
* @see javax.ws.rs.ext.MessageBodyReader
* @since 2.0
*/
public abstract T readEntity(GenericType entityType);
/**
* Read the message entity input stream as an instance of specified Java type
* using a {@link javax.ws.rs.ext.MessageBodyReader} that supports mapping the
* message entity stream onto the requested type.
*
* Method throws an {@link ProcessingException} if the content of the
* message cannot be mapped to an entity of the requested type and
* {@link IllegalStateException} in case the entity is not backed by an input
* stream or if the original entity input stream has already been consumed
* without {@link #bufferEntity() buffering} the entity data prior consuming.
*
*
* If the message does not contain an entity body {@code null} is returned.
* A non-null message instance returned from this method will be cached for
* subsequent retrievals via {@link #getEntity()}. Unless the supplied entity
* type is an {@link java.io.InputStream input stream}, this method automatically
* {@link #close() closes} the an unconsumed original response entity data stream
* if open. In case the entity data has been buffered, the buffer will be reset
* prior consuming the buffered data to enable subsequent invocations of
* {@code readEntity(...)} methods on this response.
*
*
* @param entity instance Java type.
* @param entityType the type of entity.
* @param annotations annotations that will be passed to the {@link MessageBodyReader}.
* @return the message entity; for a zero-length response entities returns {@code null}
* or a corresponding Java object that represents zero-length data.
* @throws ProcessingException if the content of the message cannot be
* mapped to an entity of the requested type.
* @throws IllegalStateException if the entity is not backed by an input stream,
* the response has been {@link #close() closed} already,
* or if the entity input stream has been fully consumed already and has
* not been buffered prior consuming.
* @see javax.ws.rs.ext.MessageBodyReader
* @since 2.0
*/
public abstract T readEntity(Class entityType, Annotation[] annotations);
/**
* Read the message entity input stream as an instance of specified Java type
* using a {@link javax.ws.rs.ext.MessageBodyReader} that supports mapping the
* message entity stream onto the requested type.
*
* Method throws an {@link ProcessingException} if the content of the
* message cannot be mapped to an entity of the requested type and
* {@link IllegalStateException} in case the entity is not backed by an input
* stream or if the original entity input stream has already been consumed
* without {@link #bufferEntity() buffering} the entity data prior consuming.
*
*
* If the message does not contain an entity body {@code null} is returned.
* A non-null message instance returned from this method will be cached for
* subsequent retrievals via {@link #getEntity()}. Unless the supplied entity
* type is an {@link java.io.InputStream input stream}, this method automatically
* {@link #close() closes} the an unconsumed original response entity data stream
* if open. In case the entity data has been buffered, the buffer will be reset
* prior consuming the buffered data to enable subsequent invocations of
* {@code readEntity(...)} methods on this response.
*
*
* @param entity instance Java type.
* @param entityType the type of entity; may be generic.
* @param annotations annotations that will be passed to the {@link MessageBodyReader}.
* @return the message entity; for a zero-length response entities returns {@code null}
* or a corresponding Java object that represents zero-length data.
* @throws ProcessingException if the content of the message cannot be
* mapped to an entity of the requested type.
* @throws IllegalStateException if the entity is not backed by an input stream,
* the response has been {@link #close() closed} already,
* or if the entity input stream has been fully consumed already and has
* not been buffered prior consuming.
* @see javax.ws.rs.ext.MessageBodyReader
* @since 2.0
*/
public abstract T readEntity(GenericType entityType, Annotation[] annotations);
/**
* Check if there is an entity available in the response. The method returns
* {@code true} if the entity is present, returns {@code false} otherwise.
*
* @return {@code true} if there is an entity present in the message,
* {@code false} otherwise.
* @throws IllegalStateException in case the response has been {@link #close() closed}.
* @since 2.0
*/
public abstract boolean hasEntity();
/**
* Buffer the message entity data.
*
* In case the message entity is backed by an unconsumed entity input stream,
* all the bytes of the original entity input stream are read and stored in a
* local buffer. The original entity input stream is consumed and automatically
* closed as part of the operation and the method returns {@code true}.
*
*
* In case the response entity instance is not backed by an unconsumed input stream
* an invocation of {@code bufferEntity} method is ignored and the method returns
* {@code false}.
*
*
* This operation is idempotent, i.e. it can be invoked multiple times with
* the same effect which also means that calling the {@code bufferEntity()}
* method on an already buffered (and thus closed) message instance is legal
* and has no further effect. Also, the result returned by the {@code bufferEntity()}
* method is consistent across all invocations of the method on the same
* {@code Response} instance.
*
*
* Buffering the message entity data allows for multiple invocations of
* {@code readEntity(...)} methods on the response instance. Note however, that
* once the response instance itself is {@link #close() closed}, the implementations
* are expected to release the buffered message entity data too. Therefore any subsequent
* attempts to read a message entity stream on such closed response will result in an
* {@link IllegalStateException} being thrown.
*
*
* @return {@code true} if the message entity input stream was available and
* was buffered successfully, returns {@code false} if the entity stream
* was not available.
* @throws ProcessingException if there was an error while buffering the entity
* input stream.
* @throws IllegalStateException in case the response has been {@link #close() closed}.
* @since 2.0
*/
public abstract boolean bufferEntity();
/**
* Close the underlying message entity input stream (if available and open)
* as well as releases any other resources associated with the response
* (e.g. {@link #bufferEntity() buffered message entity data}).
*
* This operation is idempotent, i.e. it can be invoked multiple times with the
* same effect which also means that calling the {@code close()} method on an
* already closed message instance is legal and has no further effect.
*
*
* The {@code close()} method should be invoked on all instances that
* contain an un-consumed entity input stream to ensure the resources associated
* with the instance are properly cleaned-up and prevent potential memory leaks.
* This is typical for client-side scenarios where application layer code
* processes only the response headers and ignores the response entity.
*
*
* Any attempts to manipulate (read, get, buffer) a message entity on a closed response
* will result in an {@link IllegalStateException} being thrown.
*
*
* @throws ProcessingException if there is an error closing the response.
* @since 2.0
*/
public abstract void close();
/**
* Get the media type of the message entity.
*
* @return the media type or {@code null} if there is no response entity.
* @since 2.0
*/
public abstract MediaType getMediaType();
/**
* Get the language of the message entity.
*
* @return the language of the entity or null if not specified.
* @since 2.0
*/
public abstract Locale getLanguage();
/**
* Get Content-Length value.
*
* @return Content-Length as integer if present and valid number. In other
* cases returns {@code -1}.
* @since 2.0
*/
public abstract int getLength();
/**
* Get the allowed HTTP methods from the Allow HTTP header.
*
* @return the allowed HTTP methods, all methods will returned as upper case
* strings.
* @since 2.0
*/
public abstract Set getAllowedMethods();
/**
* Get any new cookies set on the response message.
*
* @return a read-only map of cookie name (String) to Cookie.
* @since 2.0
*/
public abstract Map getCookies();
/**
* Get the entity tag.
*
* @return the entity tag, otherwise {@code null} if not present.
* @since 2.0
*/
public abstract EntityTag getEntityTag();
/**
* Get message date.
*
* @return the message date, otherwise {@code null} if not present.
* @since 2.0
*/
public abstract Date getDate();
/**
* Get the last modified date.
*
* @return the last modified date, otherwise {@code null} if not present.
* @since 2.0
*/
public abstract Date getLastModified();
/**
* Get the location.
*
* @return the location URI, otherwise {@code null} if not present.
* @since 2.0
*/
public abstract URI getLocation();
/**
* Get the links attached to the message as headers. Any links in the message
* that are relative must be resolved with respect to the actual request URI
* that produced this response. Note that request URIs may be updated by
* filters, so the actual request URI may differ from that in the original
* invocation.
*
* @return links, may return empty {@link Set} if no links are present. Does
* not return {@code null}.
* @since 2.0
*/
public abstract Set getLinks();
/**
* Check if link for relation exists.
*
* @param relation link relation.
* @return {@code true} if the link for the relation is present in the
* {@link #getHeaders() message headers}, {@code false} otherwise.
* @since 2.0
*/
public abstract boolean hasLink(String relation);
/**
* Get the link for the relation. A relative link is resolved with respect
* to the actual request URI that produced this response. Note that request
* URIs may be updated by filters, so the actual request URI may differ from
* that in the original invocation.
*
* @param relation link relation.
* @return the link for the relation, otherwise {@code null} if not present.
* @since 2.0
*/
public abstract Link getLink(String relation);
/**
* Convenience method that returns a {@link Link.Builder} for the relation.
* See {@link #getLink} for more information.
*
* @param relation link relation.
* @return the link builder for the relation, otherwise {@code null} if not
* present.
* @since 2.0
*/
public abstract Link.Builder getLinkBuilder(String relation);
/**
* See {@link #getHeaders()}.
*
* This method is considered deprecated. Users are encouraged to switch their
* code to use the {@code getHeaders()} method instead. The method may be annotated
* as {@link Deprecated @Deprecated} in a future release of JAX-RS API.
*
* @return response headers as a multivalued map.
*/
public abstract MultivaluedMap getMetadata();
/**
* Get view of the response headers and their object values.
*
* The underlying header data may be subsequently modified by the JAX-RS runtime on the
* server side. Changes in the underlying header data are reflected in this view.
*
* On the server-side, when the message is sent, the non-string values will be serialized
* using a {@link javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate} if one is available via
* {@link javax.ws.rs.ext.RuntimeDelegate#createHeaderDelegate(java.lang.Class)} for the
* class of the value or using the values {@code toString} method if a header delegate is
* not available.
*
*
* On the client side, the returned map is identical to the one returned by
* {@link #getStringHeaders()}.
*
*
* @return response headers as an object view of header values.
* @see #getStringHeaders()
* @see #getHeaderString
* @since 2.0
*/
public MultivaluedMap getHeaders() {
return getMetadata();
}
/**
* Get view of the response headers and their string values.
*
* The underlying header data may be subsequently modified by the JAX-RS runtime on
* the server side. Changes in the underlying header data are reflected in this view.
*
* @return response headers as a string view of header values.
* @see #getHeaders()
* @see #getHeaderString
* @since 2.0
*/
public abstract MultivaluedMap getStringHeaders();
/**
* Get a message header as a single string value.
*
* Each single header value is converted to String using a
* {@link javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate} if one is available
* via {@link javax.ws.rs.ext.RuntimeDelegate#createHeaderDelegate(java.lang.Class)}
* for the header value class or using its {@code toString} method if a header
* delegate is not available.
*
* @param name the message header.
* @return the message header value. If the message header is not present then
* {@code null} is returned. If the message header is present but has no
* value then the empty string is returned. If the message header is present
* more than once then the values of joined together and separated by a ','
* character.
* @see #getHeaders()
* @see #getStringHeaders()
* @since 2.0
*/
public abstract String getHeaderString(String name);
/**
* Create a new ResponseBuilder by performing a shallow copy of an
* existing Response.
*
* The returned builder has its own {@link #getHeaders() response headers}
* but the header values are shared with the original {@code Response} instance.
* The original response entity instance reference is set in the new response
* builder.
*
*
* Note that if the entity is backed by an un-consumed input stream, the
* reference to the stream is copied. In such case make sure to
* {@link #bufferEntity() buffer} the entity stream of the original response
* instance before passing it to this method.
*
*
* @param response a Response from which the status code, entity and
* {@link #getHeaders() response headers} will be copied.
* @return a new response builder.
* @since 2.0
*/
public static ResponseBuilder fromResponse(Response response) {
ResponseBuilder b = status(response.getStatus());
if (response.hasEntity()) {
b.entity(response.getEntity());
}
for (String headerName : response.getHeaders().keySet()) {
List