Skip to main content

HTTP Headers

The org.apache.juneau.http.header package contains transport-neutral header beans for all common HTTP headers. These beans implement the HttpHeader interface, which mirrors org.apache.http.Header semantics without the Apache HttpCore dependency.

Accept AcceptCharset AcceptEncoding AcceptLanguage AcceptRanges Age Allow Authorization CacheControl ClientVersion Connection ContentDisposition ContentEncoding ContentLanguage ContentLength ContentLocation ContentRange ContentType Date Debug ETag Expect Expires Forwarded From Host IfMatch IfModifiedSince IfNoneMatch IfRange IfUnmodifiedSince LastModified Location MaxForwards NoTrace Origin Pragma ProxyAuthenticate ProxyAuthorization Range Referer RetryAfter Server TE Thrown Trailer TransferEncoding Upgrade UserAgent Vary Via Warning WwwAuthenticate

These beans extend from the following transport-neutral base classes that provide data-type specific functionality, all implementing the HttpHeader interface:

HttpHeaderHttpBooleanHeader HttpCsvHeader HttpDateHeader HttpEntityTagHeader HttpEntityTagsHeader HttpIntegerHeader HttpLongHeader HttpMediaRangesHeader HttpMediaTypeHeader HttpStringHeader HttpStringRangesHeader HttpUriHeader

The Apache HttpCore–based equivalents (BasicHeader and its Basic*Header subclasses) are provided separately in the org.apache.juneau.http.classic.header package shipped by juneau-rest-common-classic.

Creator Methods​

Static methods are provided on HttpHeaders to simplify creation of headers:

HttpHeadersaccept(String)authorization(String)contentType(String)userAgent(String)

These subclasses provide various convenience methods to allow for easy fluent-style coding.

Examples
import static org.apache.juneau.http.HttpHeaders.*;
import java.time.*;

// Validates the response body content is not expired.
String expiresValue = restClient
.get(URL)
.run()
.header("Expires").getValue();

boolean expired = date(expiresValue).asZonedDateTime()
.map(d -> d.isBefore(ZonedDateTime.now()))
.orElse(false);

HeaderList​

The HeaderList class is a list of HTTP headers. It is part of the classic (org.apache.juneau.http.classic) API; the NG header beans documented above can be added to it individually, but the container itself has no NG equivalent.

Example
// Construct using builder.
HeaderList headers = HeaderList
.create()
.append(Accept.of("text/xml"))
.append("Content-Type", ()->getDynamicContentTypeFromSomewhere());

// Construct using convenience creator.
HeaderList headers = HeaderList.of(Accept.TEXT_XML, ContentType.TEXT_XML);

HeaderList is part of the classic (org.apache.juneau.http.classic) API, so its headerList(...) convenience creator is provided on the classic HttpHeaders class (not the NG class documented above) to further simplify creation of header lists.

import static org.apache.juneau.http.classic.HttpHeaders.*;

HeaderList headers = headerList(accept("text/xml"), contentType("text/xml"));

The builder class supports setting default header values (i.e. add a header to the list if it isn't otherwise in the list). Note that this is different from simply setting a value twice as using default values will not overwrite existing headers.

The following example notes the distinction:

headers = HeaderList
.create()
.set(Accept.TEXT_PLAIN)
.set(Accept.TEXT_XML);
assertObject(headers).isString("[Accept: text/xml]");

headers = HeaderList
.create()
.set(Accept.TEXT_PLAIN)
.setDefault(Accept.TEXT_XML);
assertObject(headers).isString("[Accept: text/plain]");

Various methods are provided for iterating over the headers in this list to avoid array copies.

HeaderListforEach(Consumer)forEach(String,Consumer)forEach(Predicate,Consumer)headerIterator()headerIterator(String)stream()stream(String)getAll()getAll(String)get(String)get(Class)get(String,Class)

In general, try to use these over the getAll() / getAll(String) methods that require array copies.

Similar to the way multiple parts can be collapsed into a single value, the get(String) method is special in that it will collapse multiple headers with the same name into a single comma-delimited list (see RFC 2616 Section 4.2 for rules).

The get(Class) and get(String,Class) methods are provided for working with Header-annotated beans.

Example
HeaderList headers = HeaderList.of(Accept.TEXT_JSON, Accept.TEXT_XML);

// Returns "text/json, text/xml"
Accept accept = headers.get(Accept.class);

By default, header names are treated as case-insensitive. This can be changed using the caseSensitive(boolean) method.

A VarResolver can be associated with this builder to create header values with embedded variables that are resolved at runtime.

Example
// Create a header list with dynamically-resolving values pulled from a system property.

System.setProperty("foo", "bar");

HeaderList headers = HeaderList
.create()
.resolving()
.append("X1", "$S{foo}")
.append("X2", ()->"$S{foo}");

assertObject(headers).isString("[X1: bar, X2: bar]");

The HeaderList object can be extended to defined pre-packaged lists of headers which can be used in various annotations throughout the framework.

Example
// A predefined list of headers.
public class MyHeaderList extends HeaderList {
public MyHeaderList() {
super(Accept.TEXT_XML, ContentType.TEXT_XML);
}
}

// Use it on a remote proxy to add headers on all requests.
@Remote(path="/petstore", headerList=MyHeaderList.class)
public interface PetStore {

@RemotePost("/pets")
Pet addPet(
@Content CreatePet createPet,
@Header("E-Tag") UUID etag,
@Query("debug") boolean debug
);
}