AsyncHttpClient:https://github.com/loopj/android-async-http
有时使用AsyncHttpClient时各种ResponseHandler使用很频繁。如果想要先后发送两个请求,在回调函数里面写起来很别扭,需要拆分成好几个方法,使用SyncHttpClient在回调里面写感觉怪怪的。根据它的源码摘出一个简单的、同步的LHttpClient,以备后用。做的工作只是代码搬运工,没有什么技术。参考源码版本为1.3.1和1.6.0,因为在1.6.0里面源码关联太多,有些东西不好直接使用。
谢谢@zhuxixi527提醒,post方法的时候没有传url,已经在代码上修改。但是下载资源不能编辑,只能重新上传一个了T_T
#2016-01-07修改
现在已经将代码同步到github:https://github.com/liguanliang2014/LHttpClient
修过了部分内容:增加了一个统一打印的log类,将auth的部分代码删除,修改之前的引用bug
代码结构如下:
com.net.lhttpclient
|---LHttpClient.java
|---LHttpRequest.java
|---LHttpResponse.java
|---LogUtil.java
|---RequestParams.java
|---RetryHandler.java
|---SimpleMultipartEntity.java
其中RequestParams.java、RetryHandler.java、SimpleMultipartEntity.java是从1.3.1版本直接复制过来的。
简单调用:
new Thread() {
public void run() {
LHttpClient httpClient = new LHttpClient();
LHttpResponse response = httpClient.get("http://www.baidu.com");
String str = "";
try {
str = new String(response.getResponse(), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(str);
}
}.start();
以后再写几个包装LHttpResponse的类,类似AsyncHttpClient中的各种Handler,使用会更方便。
源码:
LHttpClient.java(主要修改部分就是自己写的get、post和sendRequest方法,代码412-439行,只是实现了get和post,其余四个没有实现)
package com.net.lhttpclient;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.HttpVersion;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.SyncBasicHttpContext;
import com.loopj.android.http.PersistentCookieStore;
/**
* code from AsyncHttpClient(https://github.com/loopj/android-async-http)
*
* @author ligl01
*
*/
public class LHttpClient {
public static boolean DEBUG = true;
public static final String HEADER_CONTENT_TYPE = "Content-Type";
public static final String HEADER_CONTENT_RANGE = "Content-Range";
public static final String HEADER_CONTENT_ENCODING = "Content-Encoding";
public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
public static final String ENCODING_GZIP = "gzip";
public static final int DEFAULT_MAX_CONNECTIONS = 10;
public static final int DEFAULT_TIMEOUT = 10 * 1000;
public static final int DEFAULT_SOCKET_TIMEOUT = 10 * 1000;
public static final int DEFAULT_MAX_RETRIES = 5;
public static final int DEFAULT_RETRY_SLEEP_TIME_MILLIS = 1500;
public static final int DEFAULT_SOCKET_BUFFER_SIZE = 8192;
private int maxConnections = DEFAULT_MAX_CONNECTIONS;
private int connectTimeout = DEFAULT_TIMEOUT;
private int responseTimeout = DEFAULT_SOCKET_TIMEOUT;
private final DefaultHttpClient httpClient;
private final HttpContext httpContext;
private final Map clientHeaderMap;
public LHttpClient() {
this(80, 443);
}
public LHttpClient(int httpPort, int httpsPort) {
BasicHttpParams httpParams = new BasicHttpParams();
ConnManagerParams.setTimeout(httpParams, connectTimeout);
ConnManagerParams.setMaxConnectionsPerRoute(httpParams,
new ConnPerRouteBean(maxConnections));
ConnManagerParams.setMaxTotalConnections(httpParams,
DEFAULT_MAX_CONNECTIONS);
HttpConnectionParams.setSoTimeout(httpParams, responseTimeout);
HttpConnectionParams.setConnectionTimeout(httpParams, connectTimeout);
HttpConnectionParams.setTcpNoDelay(httpParams, true);
HttpConnectionParams.setSocketBufferSize(httpParams,
DEFAULT_SOCKET_BUFFER_SIZE);
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), httpPort));
schemeRegistry.register(new Scheme("https", SSLSocketFactory
.getSocketFactory(), httpsPort));
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(
httpParams, schemeRegistry);
httpContext = new SyncBasicHttpContext(new BasicHttpContext());
httpClient = new DefaultHttpClient(cm, httpParams);
httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(HttpRequest request, HttpContext context) {
if (!request.containsHeader(HEADER_ACCEPT_ENCODING)) {
request.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
}
for (String header : clientHeaderMap.keySet()) {
request.addHeader(header, clientHeaderMap.get(header));
}
}
});
httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
public void process(HttpResponse response, HttpContext context) {
final HttpEntity entity = response.getEntity();
final Header encoding = entity.getContentEncoding();
if (encoding != null) {
for (HeaderElement element : encoding.getElements()) {
if (element.getName().equalsIgnoreCase(ENCODING_GZIP)) {
response.setEntity(new InflatingEntity(response
.getEntity()));
break;
}
}
}
}
});
httpClient.setHttpRequestRetryHandler(new RetryHandler(
DEFAULT_MAX_RETRIES, DEFAULT_RETRY_SLEEP_TIME_MILLIS));
clientHeaderMap = new HashMap();
}
/**
* Get the underlying HttpClient instance. This is useful for setting
* additional fine-grained settings for requests by accessing the client's
* ConnectionManager, HttpParams and SchemeRegistry.
*/
public HttpClient getHttpClient() {
return this.httpClient;
}
/**
* Get the underlying HttpContext instance. This is useful for getting and
* setting fine-grained settings for requests by accessing the context's
* attributes such as the CookieStore.
*
* @return underlying HttpContext instance
*/
public HttpContext getHttpContext() {
return this.httpContext;
}
/**
* Sets an optional CookieStore to use when making requests
*
* @param cookieStore
* The CookieStore implementation to use, usually an instance of
* {@link PersistentCookieStore}
*/
public void setCookieStore(CookieStore cookieStore) {
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
}
/**
* Returns current connection timeout limit (milliseconds). By default, this
* is set to 10 seconds.
*
* @return Connection timeout limit in milliseconds
*/
public int getConnectTimeout() {
return connectTimeout;
}
/**
* Set connection timeout limit (milliseconds). By default, this is set to
* 10 seconds.
*
* @param value
* Connection timeout in milliseconds, minimal value is 1000 (1
* second).
*/
public void setConnectTimeout(int value) {
connectTimeout = value < 1000 ? DEFAULT_SOCKET_TIMEOUT : value;
final HttpParams httpParams = httpClient.getParams();
ConnManagerParams.setTimeout(httpParams, connectTimeout);
HttpConnectionParams.setConnectionTimeout(httpParams, connectTimeout);
}
/**
* Returns current response timeout limit (milliseconds). By default, this
* is set to 10 seconds.
*
* @return Response timeout limit in milliseconds
*/
public int getResponseTimeout() {
return responseTimeout;
}
/**
* Set response timeout limit (milliseconds). By default, this is set to 10
* seconds.
*
* @param value
* Response timeout in milliseconds, minimal value is 1000 (1
* second).
*/
public void setResponseTimeout(int value) {
responseTimeout = value < 1000 ? DEFAULT_SOCKET_TIMEOUT : value;
final HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setSoTimeout(httpParams, responseTimeout);
}
/**
* Sets the Proxy by it's hostname and port
*
* @param hostname
* the hostname (IP or DNS name)
* @param port
* the port number. -1 indicates the scheme default port.
*/
public void setProxy(String hostname, int port) {
final HttpHost proxy = new HttpHost(hostname, port);
final HttpParams httpParams = this.httpClient.getParams();
httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
/**
* Sets the Proxy by it's hostname,port,username and password
*
* @param hostname
* the hostname (IP or DNS name)
* @param port
* the port number. -1 indicates the scheme default port.
* @param username
* the username
* @param password
* the password
*/
public void setProxy(String hostname, int port, String username,
String password) {
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(hostname, port),
new UsernamePasswordCredentials(username, password));
final HttpHost proxy = new HttpHost(hostname, port);
final HttpParams httpParams = this.httpClient.getParams();
httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
/**
* Sets the SSLSocketFactory to user when making requests. By default, a
* new, default SSLSocketFactory is used.
*
* @param sslSocketFactory
* the socket factory to use for https requests.
*/
public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
this.httpClient.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", sslSocketFactory, 443));
}
/**
* Sets the maximum number of retries and timeout for a particular Request.
*
* @param retries
* maximum number of retries per request
* @param timeout
* sleep between retries in milliseconds
*/
public void setMaxRetriesAndTimeout(int retries, int timeout) {
this.httpClient.setHttpRequestRetryHandler(new RetryHandler(retries,
timeout));
}
/**
* Will, before sending, remove all headers currently present in
* AsyncHttpClient instance, which applies on all requests this client makes
*/
public void removeAllHeaders() {
clientHeaderMap.clear();
}
/**
* Sets headers that will be added to all requests this client makes (before
* sending).
*
* @param header
* the name of the header
* @param value
* the contents of the header
*/
public void addHeader(String header, String value) {
clientHeaderMap.put(header, value);
}
/**
* Remove header from all requests this client makes (before sending).
*
* @param header
* the name of the header
*/
public void removeHeader(String header) {
clientHeaderMap.remove(header);
}
// /**
// * Sets basic authentication for the request. Uses AuthScope.ANY. This is
// * the same as setBasicAuth('username','password',AuthScope.ANY)
// *
// * @param username
// * Basic Auth username
// * @param password
// * Basic Auth password
// */
// public void setBasicAuth(String username, String password) {
// setBasicAuth(username, password, false);
// }
//
// /**
// * Sets basic authentication for the request. Uses AuthScope.ANY. This is
// * the same as setBasicAuth('username','password',AuthScope.ANY)
// *
// * @param username
// * Basic Auth username
// * @param password
// * Basic Auth password
// * @param preemtive
// * sets authorization in preemtive manner
// */
// public void setBasicAuth(String username, String password, boolean preemtive) {
// setBasicAuth(username, password, null, preemtive);
// }
//
// /**
// * Sets basic authentication for the request. You should pass in your
// * AuthScope for security. It should be like this
// * setBasicAuth("username","password", new
// * AuthScope("host",port,AuthScope.ANY_REALM))
// *
// * @param username
// * Basic Auth username
// * @param password
// * Basic Auth password
// * @param scope
// * - an AuthScope object
// */
// public void setBasicAuth(String username, String password, AuthScope scope) {
// setBasicAuth(username, password, scope, false);
// }
//
// /**
// * Sets basic authentication for the request. You should pass in your
// * AuthScope for security. It should be like this
// * setBasicAuth("username","password", new
// * AuthScope("host",port,AuthScope.ANY_REALM))
// *
// * @param username
// * Basic Auth username
// * @param password
// * Basic Auth password
// * @param scope
// * an AuthScope object
// * @param preemtive
// * sets authorization in preemtive manner
// */
// public void setBasicAuth(String username, String password, AuthScope scope,
// boolean preemtive) {
// UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(
// username, password);
// setCredentials(scope, credentials);
// setAuthenticationPreemptive(preemtive);
// }
//
// public void setCredentials(AuthScope authScope, Credentials credentials) {
// if (credentials == null) {
// LogUtil.d("Provided credentials are null, not setting");
// return;
// }
// this.httpClient.getCredentialsProvider().setCredentials(
// authScope == null ? AuthScope.ANY : authScope, credentials);
// }
//
// /**
// * Sets HttpRequestInterceptor which handles authorization in preemtive way,
// * as workaround you can use call
// * `AsyncHttpClient.addHeader("Authorization",
// * "Basic base64OfUsernameAndPassword==")`
// *
// * @param isPreemtive
// * whether the authorization is processed in preemtive way
// */
// public void setAuthenticationPreemptive(boolean isPreemtive) {
// if (isPreemtive) {
// httpClient.addRequestInterceptor(
// new PreemtiveAuthorizationHttpRequestInterceptor(), 0);
// } else {
// httpClient
// .removeRequestInterceptorByClass(PreemtiveAuthorizationHttpRequestInterceptor.class);
// }
// }
public LHttpResponse get(String url) {
return get(url, null);
}
public LHttpResponse get(String url, RequestParams params) {
return sendRequest(httpClient, httpContext, new HttpGet(
getUrlWithQueryString(url, params)), null);
}
public LHttpResponse post(String url) {
return post(url, null);
}
public LHttpResponse post(String url, RequestParams params) {
return post(url, paramsToEntity(params), null);
}
public LHttpResponse post(String url, HttpEntity entity, String contentType) {
return sendRequest(httpClient, httpContext,
addEntityToRequestBase(new HttpPost(url), entity), contentType);
}
private LHttpResponse sendRequest(DefaultHttpClient client,
HttpContext httpContext, HttpUriRequest uriRequest,
String contentType) {
LHttpRequest request = new LHttpRequest(httpClient, httpContext, uriRequest);
return request.request();
}
private HttpEntityEnclosingRequestBase addEntityToRequestBase(
HttpEntityEnclosingRequestBase requestBase, HttpEntity entity) {
if (entity != null) {
requestBase.setEntity(entity);
}
return requestBase;
}
private HttpEntity paramsToEntity(RequestParams params) {
HttpEntity entity = null;
if (params != null) {
entity = params.getEntity();
}
return entity;
}
private String getUrlWithQueryString(String url, RequestParams params) {
if (params != null) {
String paramString = params.getParamString();
url += "?" + paramString;
}
return url;
}
/**
* This horrible hack is required on Android, due to implementation of BasicManagedEntity, which
* doesn't chain call consumeContent on underlying wrapped HttpEntity
*
* @param entity HttpEntity, may be null
*/
public static void endEntityViaReflection(HttpEntity entity) {
if (entity instanceof HttpEntityWrapper) {
try {
Field f = null;
Field[] fields = HttpEntityWrapper.class.getDeclaredFields();
for (Field ff : fields) {
if (ff.getName().equals("wrappedEntity")) {
f = ff;
break;
}
}
if (f != null) {
f.setAccessible(true);
HttpEntity wrapped = (HttpEntity) f.get(entity);
if (wrapped != null) {
wrapped.consumeContent();
}
}
} catch (Throwable t) {
LogUtil.e("wrappedEntity consume", t);
}
}
}
/**
* Checks the InputStream if it contains GZIP compressed data
*
* @param inputStream
* InputStream to be checked
* @return true or false if the stream contains GZIP compressed data
* @throws java.io.IOException
*/
public static boolean isInputStreamGZIPCompressed(
final PushbackInputStream inputStream) throws IOException {
if (inputStream == null)
return false;
byte[] signature = new byte[2];
int readStatus = inputStream.read(signature);
inputStream.unread(signature);
int streamHeader = ((int) signature[0] & 0xff)
| ((signature[1] << 8) & 0xff00);
return readStatus == 2 && GZIPInputStream.GZIP_MAGIC == streamHeader;
}
/**
* A utility function to close an input stream without raising an exception.
*
* @param is
* input stream to close safely
*/
public static void silentCloseInputStream(InputStream is) {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
LogUtil.w("Cannot close input stream", e);
}
}
/**
* Enclosing entity to hold stream of gzip decoded data for accessing
* HttpEntity contents
*/
private static class InflatingEntity extends HttpEntityWrapper {
public InflatingEntity(HttpEntity wrapped) {
super(wrapped);
}
InputStream wrappedStream;
PushbackInputStream pushbackStream;
GZIPInputStream gzippedStream;
@Override
public InputStream getContent() throws IOException {
wrappedStream = wrappedEntity.getContent();
pushbackStream = new PushbackInputStream(wrappedStream, 2);
if (isInputStreamGZIPCompressed(pushbackStream)) {
gzippedStream = new GZIPInputStream(pushbackStream);
return gzippedStream;
} else {
return pushbackStream;
}
}
@Override
public long getContentLength() {
return wrappedEntity == null ? 0 : wrappedEntity.getContentLength();
}
@Override
public void consumeContent() throws IOException {
LHttpClient.silentCloseInputStream(wrappedStream);
LHttpClient.silentCloseInputStream(pushbackStream);
LHttpClient.silentCloseInputStream(gzippedStream);
super.consumeContent();
}
}
}
package com.net.lhttpclient;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.ByteArrayBuffer;
public class LHttpRequest {
protected static final int BUFFER_SIZE = 4096;
private final AbstractHttpClient client;
private final HttpContext context;
private final HttpUriRequest request;
private int executionCount;
public LHttpRequest(AbstractHttpClient client, HttpContext context, HttpUriRequest request) {
this.client = client;
this.context = context;
this.request = request;
}
public LHttpResponse request() {
LHttpResponse lHttpResponse = new LHttpResponse();
HttpResponse httpResponse = null;
try {
httpResponse = makeRequestWithRetries();
} catch (IOException e) {
LogUtil.w("makeRequestWithRetries exception", e);
lHttpResponse.setSuccess(false);
lHttpResponse.setThrowable(e);
}
if(httpResponse != null) {
byte[] responseBody;
StatusLine status = httpResponse.getStatusLine();
try {
responseBody = getResponseData(httpResponse.getEntity());
if (status.getStatusCode() >= 300) {
lHttpResponse.setSuccess(false);
lHttpResponse.setStatusCode(status.getStatusCode());
lHttpResponse.setResponse(responseBody);
lHttpResponse.setThrowable(new HttpResponseException(status.getStatusCode(), status.getReasonPhrase()));
} else {
lHttpResponse.setSuccess(true);
lHttpResponse.setStatusCode(status.getStatusCode());
lHttpResponse.setResponse(responseBody);
}
} catch (IOException e) {
LogUtil.w("getResponseData exception", e);
lHttpResponse.setSuccess(false);
lHttpResponse.setThrowable(e);
}
}
return lHttpResponse;
}
/**
* Returns byte array of response HttpEntity contents
*
* @param entity can be null
* @return response entity body or null
* @throws java.io.IOException if reading entity or creating byte array failed
*/
byte[] getResponseData(HttpEntity entity) throws IOException {
byte[] responseBody = null;
if (entity != null) {
InputStream instream = entity.getContent();
if (instream != null) {
long contentLength = entity.getContentLength();
if (contentLength > Integer.MAX_VALUE) {
throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
}
int buffersize = (contentLength <= 0) ? BUFFER_SIZE : (int) contentLength;
try {
ByteArrayBuffer buffer = new ByteArrayBuffer(buffersize);
try {
byte[] tmp = new byte[BUFFER_SIZE];
int l, count = 0;
// do not send messages if request has been cancelled
while ((l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) {
count += l;
buffer.append(tmp, 0, l);
// sendProgressMessage(count, (int) (contentLength <= 0 ? 1 : contentLength));
}
} finally {
LHttpClient.silentCloseInputStream(instream);
LHttpClient.endEntityViaReflection(entity);
}
responseBody = buffer.toByteArray();
} catch (OutOfMemoryError e) {
System.gc();
throw new IOException("File too large to fit into available memory");
}
}
}
return responseBody;
}
private HttpResponse makeRequest() throws IOException {
return client.execute(request, context);
}
private HttpResponse makeRequestWithRetries() throws IOException {
boolean retry = true;
IOException cause = null;
HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();
try {
while (retry) {
try {
return makeRequest();
} catch (UnknownHostException e) {
// switching between WI-FI and mobile data networks can cause a retry which then results in an UnknownHostException
// while the WI-FI is initialising. The retry logic will be invoked here, if this is NOT the first retry
// (to assist in genuine cases of unknown host) which seems better than outright failure
cause = new IOException("UnknownHostException exception: " + e.getMessage());
retry = (executionCount > 0) && retryHandler.retryRequest(cause, ++executionCount, context);
} catch (NullPointerException e) {
// there's a bug in HttpClient 4.0.x that on some occasions causes
// DefaultRequestExecutor to throw an NPE, see
// http://code.google.com/p/android/issues/detail?id=5255
cause = new IOException("NPE in HttpClient: " + e.getMessage());
retry = retryHandler.retryRequest(cause, ++executionCount, context);
} catch (IOException e) {
cause = e;
retry = retryHandler.retryRequest(cause, ++executionCount, context);
}
}
} catch (Exception e) {
// catch anything else to ensure failure message is propagated
// Log.e("AsyncHttpRequest", "Unhandled exception origin cause", e);
cause = new IOException("Unhandled exception: " + e.getMessage());
}
// cleaned up to throw IOException
throw (cause);
}
}
package com.net.lhttpclient;
public class LHttpResponse {
private boolean success;
private byte[] response;
private int statusCode;
private Throwable throwable;
/**
* 将byte数组转换为字符串,如果发生异常返回null
* @param charsetName 比如utf-8、gbk等等
* @return 字符串,如果发生异常返回null
*/
public String getTextResponse(String charsetName) {
if(response == null) {
return null;
}
try {
return new String(response, charsetName);
} catch(Exception e) {
LogUtil.e("getTextResponse", e);
}
return null;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public byte[] getResponse() {
return response;
}
public void setResponse(byte[] response) {
this.response = response;
}
public int getStatusCode() {
return statusCode;
}
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
public Throwable getThrowable() {
return throwable;
}
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
}