Java tutorial
/* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.squareup.okhttp; import com.squareup.okhttp.internal.http.HttpMethod; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.List; /** * An HTTP request. Instances of this class are immutable if their {@link #body} * is null or itself immutable. */ public final class Request { private final HttpUrl url; private final String method; private final Headers headers; private final RequestBody body; private final Object tag; private volatile URL javaNetUrl; // Lazily initialized. private volatile URI javaNetUri; // Lazily initialized. private volatile CacheControl cacheControl; // Lazily initialized. private Request(Builder builder) { this.url = builder.url; this.method = builder.method; this.headers = builder.headers.build(); this.body = builder.body; this.tag = builder.tag != null ? builder.tag : this; } public HttpUrl httpUrl() { return url; } public URL url() { URL result = javaNetUrl; return result != null ? result : (javaNetUrl = url.url()); } public URI uri() throws IOException { try { URI result = javaNetUri; return result != null ? result : (javaNetUri = url.uri()); } catch (IllegalStateException e) { throw new IOException(e.getMessage()); } } public String urlString() { return url.toString(); } public String method() { return method; } public Headers headers() { return headers; } public String header(String name) { return headers.get(name); } public List<String> headers(String name) { return headers.values(name); } public RequestBody body() { return body; } public Object tag() { return tag; } public Builder newBuilder() { return new Builder(this); } /** * Returns the cache control directives for this response. This is never null, * even if this response contains no {@code Cache-Control} header. */ public CacheControl cacheControl() { CacheControl result = cacheControl; return result != null ? result : (cacheControl = CacheControl.parse(headers)); } public boolean isHttps() { return url.isHttps(); } @Override public String toString() { return "Request{method=" + method + ", url=" + url + ", tag=" + (tag != this ? tag : null) + '}'; } public static class Builder { private HttpUrl url; private String method; private Headers.Builder headers; private RequestBody body; private Object tag; public Builder() { this.method = "GET"; this.headers = new Headers.Builder(); } private Builder(Request request) { this.url = request.url; this.method = request.method; this.body = request.body; this.tag = request.tag; this.headers = request.headers.newBuilder(); } public Builder url(HttpUrl url) { if (url == null) throw new IllegalArgumentException("url == null"); this.url = url; return this; } /** * Sets the URL target of this request. * * @throws IllegalArgumentException if {@code url} is not a valid HTTP or HTTPS URL. Avoid this * exception by calling {@link HttpUrl#parse}; it returns null for invalid URLs. */ public Builder url(String url) { if (url == null) throw new IllegalArgumentException("url == null"); // Silently replace websocket URLs with HTTP URLs. if (url.regionMatches(true, 0, "ws:", 0, 3)) { url = "http:" + url.substring(3); } else if (url.regionMatches(true, 0, "wss:", 0, 4)) { url = "https:" + url.substring(4); } HttpUrl parsed = HttpUrl.parse(url); if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url); return url(parsed); } /** * Sets the URL target of this request. * * @throws IllegalArgumentException if the scheme of {@code url} is not {@code http} or {@code * https}. */ public Builder url(URL url) { if (url == null) throw new IllegalArgumentException("url == null"); HttpUrl parsed = HttpUrl.get(url); if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url); return url(parsed); } /** * Sets the header named {@code name} to {@code value}. If this request * already has any headers with that name, they are all replaced. */ public Builder header(String name, String value) { headers.set(name, value); return this; } /** * Adds a header with {@code name} and {@code value}. Prefer this method for * multiply-valued headers like "Cookie". * * <p>Note that for some headers including {@code Content-Length} and {@code Content-Encoding}, * OkHttp may replace {@code value} with a header derived from the request body. */ public Builder addHeader(String name, String value) { headers.add(name, value); return this; } public Builder removeHeader(String name) { headers.removeAll(name); return this; } /** Removes all headers on this builder and adds {@code headers}. */ public Builder headers(Headers headers) { this.headers = headers.newBuilder(); return this; } /** * Sets this request's {@code Cache-Control} header, replacing any cache * control headers already present. If {@code cacheControl} doesn't define * any directives, this clears this request's cache-control headers. */ public Builder cacheControl(CacheControl cacheControl) { String value = cacheControl.toString(); if (value.isEmpty()) return removeHeader("Cache-Control"); return header("Cache-Control", value); } public Builder get() { return method("GET", null); } public Builder head() { return method("HEAD", null); } public Builder post(RequestBody body) { return method("POST", body); } public Builder delete(RequestBody body) { return method("DELETE", body); } public Builder delete() { return delete(RequestBody.create(null, new byte[0])); } public Builder put(RequestBody body) { return method("PUT", body); } public Builder patch(RequestBody body) { return method("PATCH", body); } public Builder method(String method, RequestBody body) { if (method == null || method.length() == 0) { throw new IllegalArgumentException("method == null || method.length() == 0"); } if (body != null && !HttpMethod.permitsRequestBody(method)) { throw new IllegalArgumentException("method " + method + " must not have a request body."); } if (body == null && HttpMethod.requiresRequestBody(method)) { throw new IllegalArgumentException("method " + method + " must have a request body."); } this.method = method; this.body = body; return this; } /** * Attaches {@code tag} to the request. It can be used later to cancel the * request. If the tag is unspecified or null, the request is canceled by * using the request itself as the tag. */ public Builder tag(Object tag) { this.tag = tag; return this; } public Request build() { if (url == null) throw new IllegalStateException("url == null"); return new Request(this); } } }