Response.java
package com.goebl.david;
import java.net.HttpURLConnection;
/**
* Holds data about the response message returning from HTTP request.
*
* @author hgoebl
*/
public class Response<T> {
final Request request;
int statusCode;
String responseMessage;
T body;
Object errorBody;
HttpURLConnection connection;
Response(Request request) {
this.request = request;
}
void setBody(Object body) {
this.body = (T) body;
}
/**
* Access to the <code>Request</code> object (which will not be very useful in most cases).
* @return the request object which was responsible for creating this response.
*/
public Request getRequest() {
return request;
}
/**
* Returns the payload of the response converted to the given type.
* @return the converted payload (can be null).
*/
public T getBody() {
return body;
}
/**
* Get the body which was returned in case of error (HTTP-Code >= 400).
* <br>
* The type of the error body depends on following factors:
* <ul>
* <li>
* <code>Content-Type</code> header (overrules the expected return type of the response)
* </li>
* <li>
* The expected type (see <code>asXyz()</code>). We try to coerce the error body to this type.
* In case of REST services, where often a JSONObject is the normal response body, the error body
* will be converted to JSONObject if possible. <code>JSONArray</code> is not expected to be the
* error body.
* </li>
* </ul>
* If converting the error body is not successful, <code>String</code> and <code>byte[]</code> is used as
* a fallback. You have to check the type with <code>instanceof</code> or try/catch the cast.
* @return the error body converted to an object (see above) or <code>null</code> if there is no body or
* no error.
*/
public Object getErrorBody() {
return errorBody;
}
/**
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html#responseCode">
* HttpURLConnection.responseCode</a>
* @return An int representing the three digit HTTP Status-Code.
*/
public int getStatusCode() {
return statusCode;
}
/**
* The first line returned by the web-server, like "HTTP/1.1 200 OK".
* @return first header
*/
public String getStatusLine() {
return connection.getHeaderField(null);
}
/**
* Was the request successful (returning a 2xx status code)?
* @return <code>true</code> when status code is between 200 and 299, else <code>false</code>
*/
public boolean isSuccess() {
return (statusCode / 100) == 2; // 200, 201, 204, ...
}
/**
* Returns the text explaining the status code.
* @return e.g. "Moved Permanently", "Created", ...
*/
public String getResponseMessage() {
return responseMessage;
}
/**
* Returns the MIME-type of the response body.
* <br>
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getContentType()">
* URLConnection.getContentType()</a>
*
* @return e.g. "application/json", "text/plain", ...
*/
public String getContentType() {
return connection.getContentType();
}
/**
* Returns the date when the request was created (server-time).
* <br>
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getDate()">
* URLConnection.getDate()</a>
*
* @return the parsed "Date" header as millis or <code>0</code> if this header was not set.
*/
public long getDate() {
return connection.getDate();
}
/**
* Returns the value of the expires header field.
* <br>
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getExpiration()">
* URLConnection.getExpiration()</a>
*
* @return the expiration date of the resource, or 0 if not known.
*/
public long getExpiration() {
return connection.getExpiration();
}
/**
* Returns the value of the last-modified header field.
* <br>
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getLastModified()">
* URLConnection.getLastModified()</a>
*
* @return the date the resource was last modified, or 0 if not known.
*/
public long getLastModified() {
return connection.getLastModified();
}
/**
* Returns the value of the named header field.
* <br>
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getHeaderField(java.lang.String)">
* URLConnection.getHeaderField()</a>
*
* @param name name of the header field
* @return the value of the named header field, or null
*/
public String getHeaderField (String name) {
return connection.getHeaderField(name);
}
/**
* Returns the value of the named field parsed as date (Millis since 1970).
* <br>
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getHeaderFieldDate(java.lang.String,+long)">
* URLConnection.getHeaderFieldDate()</a>
*
* @param field name of the header field
* @param defaultValue the default value if the field is not present or malformed
* @return the value of the named header field, or the given default value
*/
public long getHeaderFieldDate (String field, long defaultValue) {
return connection.getHeaderFieldDate(field, defaultValue);
}
/**
* Returns the value of the named field parsed as a number.
* <br>
* See <a href="http://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getHeaderFieldInt(java.lang.String,+int)">
* URLConnection.getHeaderFieldInt()</a>
*
* @param field name of the header field
* @param defaultValue the default value if the field is not present or malformed
* @return the value of the named header field, or the given default value
*/
public int getHeaderFieldInt(String field, int defaultValue) {
return connection.getHeaderFieldInt(field, defaultValue);
}
/**
* Get the "real" connection, typically to call some getters which are not provided by this Response object.
* @return the connection object (many methods throw IllegalStateException depending on the internal state).
*/
public HttpURLConnection getConnection() {
return connection;
}
/**
* A shortcut to check for successful status codes and throw exception in case of non-2xx status codes.
* <br>
* In many cases you will call {@link com.goebl.david.Request#ensureSuccess()} instead of this method.
* But there might be cases where you want to inspect the response-object first (check header values) and
* then have a short exit where the response-code is not suitable for further normal processing.
*/
public void ensureSuccess() {
if (!isSuccess()) {
throw new WebbException("Request failed: " + statusCode + " " + responseMessage, (Response) this);
}
}
}