HTTP Headers
The org.apache.juneau.http.header package contains implementations of
org.apache.http.Header
for all common HTTP headers.
These headers extend from the following classes that provide data-type specific functionality:
Creator Methods
Static methods are provided on HttpHeaders to simplify creation of headers:
These subclasses provide various convenience methods to allow for easy fluent-style coding.
// Validates the response body content is not expired.
restClient
.get(URL)
.run()
.getHeader("Expires").asDateHeader().assertZonedDateTime().isLessThan(new Date());
HeaderList
The HeaderList class is a list of HTTP headers.
// 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);
Static methods are provided on HttpHeaders to further simplify creation of header lists.
import static org.apache.juneau.http.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.
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.
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.
// 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.
// 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
);
}