com.goebl.david.Request Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of david-webb Show documentation
Show all versions of david-webb Show documentation
Lightweight Java HTTP-Client for calling JSON REST-Services (especially for Android)
package com.goebl.david;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Builder for an HTTP request.
*
* You can some "real-life" usage examples at
* github.com/hgoebl/DavidWebb.
*
*
* @author hgoebl
*/
public class Request {
public enum Method {
GET, POST, PUT, DELETE
}
private final Webb webb;
final Method method;
final String uri;
Map params;
Map headers;
Object payload;
boolean streamPayload;
boolean useCaches;
Integer connectTimeout;
Integer readTimeout;
Long ifModifiedSince;
Boolean followRedirects;
boolean ensureSuccess;
boolean compress;
Request(Webb webb, Method method, String uri) {
this.webb = webb;
this.method = method;
this.uri = uri;
this.followRedirects = webb.followRedirects;
}
/**
* Set (or overwrite) a parameter.
*
* The parameter will be used to create a query string for GET-requests and as the body for POST-requests
* with MIME-type application/x-www-form-urlencoded
,
* @param name the name of the parameter (it's better to use only contain ASCII characters)
* @param value the value of the parameter; null
will be converted to empty string, for all other
* objects to toString()
method converts it to String
* @return this
for method chaining (fluent API)
*/
public Request param(String name, Object value) {
if (params == null) {
params = new LinkedHashMap();
}
params.put(name, value);
return this;
}
/**
* Set (or overwrite) a HTTP header value.
*
* Setting a header this way has the highest precedence and overrides a header value set on a {@link Webb}
* instance ({@link Webb#setDefaultHeader(String, Object)}) or a global header
* ({@link Webb#setGlobalHeader(String, Object)}).
*
* Using null
or empty String is not allowed for name and value.
*
* @param name name of the header (HTTP-headers are not case-sensitive, but if you want to override your own
* headers, you have to use identical strings for the name. There are some frequently used header
* names as constants in {@link Webb}, see HDR_xxx.
* @param value the value for the header. Following types are supported, all other types use toString
* of the given object:
*
* - {@link java.util.Date} is converted to RFC1123 compliant String
* - {@link java.util.Calendar} is converted to RFC1123 compliant String
*
* @return this
for method chaining (fluent API)
*/
public Request header(String name, Object value) {
if (headers == null) {
headers = new LinkedHashMap();
}
headers.put(name, value);
return this;
}
/**
* Set the payload for the request.
*
* Using this method together with {@link #param(String, Object)} has the effect of body
being
* ignored without notice. The method can be called more than once: the value will be stored and converted
* to bytes later.
*
* Following types are supported for the body:
*
* -
*
null
clears the body
*
* -
* {@link org.json.JSONObject}, HTTP header 'Content-Type' will be set to JSON, if not set
*
* -
* {@link org.json.JSONArray}, HTTP header 'Content-Type' will be set to JSON, if not set
*
* -
* {@link java.lang.String}, HTTP header 'Content-Type' will be set to TEXT, if not set;
* Text will be converted to UTF-8 bytes.
*
* -
*
byte[]
the easiest way for DavidWebb - it's just passed through.
* HTTP header 'Content-Type' will be set to BINARY, if not set.
*
* -
* {@link java.io.File}, HTTP header 'Content-Type' will be set to BINARY, if not set;
* The file gets streamed to the web-server and 'Content-Length' will be set to the number
* of bytes of the file. There is absolutely no conversion done. So if you want to upload
* e.g. a text-file and convert it to another encoding than stored on disk, you have to do
* it by yourself.
*
* -
* {@link java.io.InputStream}, HTTP header 'Content-Type' will be set to BINARY, if not set;
* Similar to
File
. Content-Length cannot be set (which has some drawbacks compared
* to knowing the size of the body in advance).
* You have to care for closing the stream!
*
*
*
* @param body the payload
* @return this
for method chaining (fluent API)
*/
public Request body(Object body) {
if (method == Method.GET || method == Method.DELETE) {
throw new IllegalStateException("body not allowed for request method " + method);
}
this.payload = body;
this.streamPayload = body instanceof File || body instanceof InputStream;
return this;
}
/**
* Enable compression for uploaded data.
*
* Before you enable compression, you should find out, whether the web server you are talking to
* supports this. As compression has not to be implemented for HTTP and standard RFC2616 had only
* compression for downloaded resources in mind, in special cases it makes absolutely sense to
* compress the posted data.
* Your web application should inspect the 'Content-Encoding' header and implement the compression
* token provided by this client. By now only 'gzip' encoding token is used. If you need 'deflate'
* create an issue.
*
* @return this
for method chaining (fluent API)
*/
public Request compress() {
compress = true;
return this;
}
/**
* See
* URLConnection.useCaches
*
* If you don't want your requests delivered from a cache, you don't have to call this method,
* because false
is the default.
*
* @param useCaches If true
, the protocol is allowed to use caching whenever it can.
* @return this
for method chaining (fluent API)
*/
public Request useCaches(boolean useCaches) {
this.useCaches = useCaches;
return this;
}
/**
* See
* URLConnection.setIfModifiedSince()
* @param ifModifiedSince A nonzero value gives a time as the number of milliseconds since January 1, 1970, GMT.
* The object is fetched only if it has been modified more recently than that time.
* @return this
for method chaining (fluent API)
*/
public Request ifModifiedSince(long ifModifiedSince) {
this.ifModifiedSince = ifModifiedSince;
return this;
}
/**
* See
* URLConnection.setConnectTimeout
* @param connectTimeout sets a specified timeout value, in milliseconds. 0
means infinite timeout.
* @return this
for method chaining (fluent API)
*/
public Request connectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}
/**
* See
*
* @param readTimeout Sets the read timeout to a specified timeout, in milliseconds.
* 0
means infinite timeout.
* @return this
for method chaining (fluent API)
*/
public Request readTimeout(int readTimeout) {
this.readTimeout = readTimeout;
return this;
}
/**
* See
* .
*
* Use this method to set the behaviour for this single request when receiving redirect responses.
* If you want to change the behaviour for all your requests, call {@link Webb#setFollowRedirects(boolean)}.
* @param auto true
to automatically follow redirects (HTTP status code 3xx).
* Default value comes from HttpURLConnection and should be true
.
* @return this
for method chaining (fluent API)
*/
public Request followRedirects(boolean auto) {
this.followRedirects = auto;
return this;
}
/**
* By calling this method, the HTTP status code is checked and a WebbException
is thrown if
* the status code is not something like 2xx.
*
* Be careful! If you request resources e.g. with {@link #ifModifiedSince(long)}, an exception will also be
* thrown in the positive case of 304 Not Modified
.
*
* @return this
for method chaining (fluent API)
*/
public Request ensureSuccess() {
this.ensureSuccess = true;
return this;
}
/**
* Execute the request and expect the result to be convertible to String
.
* @return the created Response
object carrying the payload from the server as String
*/
public Response asString() {
return webb.execute(this, String.class);
}
/**
* Execute the request and expect the result to be convertible to JSONObject
.
* @return the created Response
object carrying the payload from the server as JSONObject
*/
public Response asJsonObject() {
return webb.execute(this, JSONObject.class);
}
/**
* Execute the request and expect the result to be convertible to JSONArray
.
* @return the created Response
object carrying the payload from the server as JSONArray
*/
public Response asJsonArray() {
return webb.execute(this, JSONArray.class);
}
/**
* Execute the request and expect the result to be convertible to byte[]
.
* @return the created Response
object carrying the payload from the server as byte[]
*/
public Response asBytes() {
return (Response) webb.execute(this, Const.BYTE_ARRAY_CLASS);
}
/**
* Execute the request and expect no result payload (only status-code and headers).
* @return the created Response
object where no payload is expected or simply will be ignored.
*/
public Response asVoid() {
return webb.execute(this, Void.class);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy