package com.pacific.free.pos.http;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.alibaba.fastjson.JSONObject;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
import com.pacific.free.pos.Const;
import com.pacific.free.pos.util.Utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HttpRequestMultipartFactory <T> {
private static String authCode;
private static String devId;
private static String clientDevId;
private static String clientId;
private final Context context;
private final String url;
private final RequestMethod method;
private byte[] requestBody;
private final ResponseParser<T> parser;
private String contentType;
private Long timeoutMillis;
private Map<String, String> headers;
private Response.Listener<T> successListener;
private Response.ErrorListener errorListener;
private List<NameValuePair> getParameters;
private File mfile;
private HttpRequestMultipartFactory(Context context, String url, RequestMethod method, ResponseParser<T> parser) {
this.context = context;
this.url = url;
this.method = method;
this.parser = parser;
this.timeoutMillis = 15_000L;//默认超时时间是15s
}
public static void initSign(String authCode, String devId, String clientDevId, String clientId) {
HttpRequestMultipartFactory.authCode = authCode;
HttpRequestMultipartFactory.devId = devId;
HttpRequestMultipartFactory.clientDevId = clientDevId;
HttpRequestMultipartFactory.clientId = clientId;
}
private static boolean signInited() {
return authCode == null || devId == null || clientDevId == null || clientId == null;
}
/**
* 创建普通实例
*
* @param context context
* @param url 请求url
* @param method 请求方法
* @param parser 返回值反序列化工具,JSON反序列化已实现
* @param <T> 返回值类型
* @return 新的factory对象
*/
public static <T> HttpRequestMultipartFactory<T> newInstance(Context context, String url, RequestMethod method, ResponseParser<T> parser) {
return new HttpRequestMultipartFactory<>(context, url, method, parser);
}
/**
* 创建签名请求实例(用于和服务端通信)
*
* @param context context
* @param url 请求url
* @param method 请求方法
* @param parser 返回值反序列化工具,JSON反序列化已实现
* @param <T> 返回值类型
* @return 新的factory对象
*/
public static <T> HttpRequestMultipartFactory<T> newSignInstance(Context context, String url, RequestMethod method, ResponseParser<T> parser) {
HttpRequestMultipartFactory<T> factory = new HttpRequestMultipartFactory<>(context, url, method, parser);
factory.addHeader("x-user-id", Const.x_user_id).addHeader("x-debug", Const.debug).addHeader("x-devid", "12345");
return factory;
}
/**
* 添加Request Query String Param参数
*
* @param key key
* @param values value,允许多个
* @return this
*/
public HttpRequestMultipartFactory<T> addQueryStringParams(String key, String... values) {
if (values == null || values.length == 0) {
return this;
}
if (getParameters == null) {
getParameters = new ArrayList<>();
}
for (String value : values) {
getParameters.add(new NameValuePair(key, value));
}
return this;
}
/**
* 添加Request Body
*
* @param entity 二进制格式的Request Body
* @param contentType ContentType
* @return this
*/
public HttpRequestMultipartFactory<T> setRequestBody(byte[] entity, String contentType) {
requestBody = entity;
this.contentType = contentType;
return this;
}
public HttpRequestMultipartFactory<T> setFile(File file) {
this.mfile=file;
return this;
}
/**
* 添加JSONObject作为Request Body
*
* @param entity 作为Request Body的JSON对象
* @return this
*/
public HttpRequestMultipartFactory<T> setJsonObjectRequestBody(JSONObject entity) {
try {
requestBody = entity.toJSONString().getBytes("utf-8");
contentType = "application/json; charset=utf-8";
} catch (UnsupportedEncodingException ignored) {
}
return this;
}
/**
* 设置成功回调
*
* @param listener 成功回调
* @return this
*/
public HttpRequestMultipartFactory<T> onSuccess(Response.Listener<T> listener) {
this.successListener = listener;
return this;
}
/**
* 设置失败回调
*
* @param listener 失败回调
* @return this
*/
public HttpRequestMultipartFactory<T> onFail(Response.ErrorListener listener) {
this.errorListener = listener;
return this;
}
public HttpRequestMultipartFactory<T> setTimeout(Long timeoutMillis) {
this.timeoutMillis = timeoutMillis;
return this;
}
/**
* 添加HTTP Header
*
* @param key Header key
* @param value Header Value
* @return this
*/
public HttpRequestMultipartFactory<T> addHeader(String key, String value) {
if (headers == null) {
headers = new HashMap<>();
}
headers.put(key, value);
return this;
}
private String buildUrl() {
Uri uri = Uri.parse(url);
Uri.Builder builder = uri.buildUpon();
if (getParameters != null) {
for (NameValuePair param : getParameters) {
builder.appendQueryParameter(param.getName(), param.getValue());
}
}
return builder.build().toString();
}
/**
* 执行请求
*
* @return Request对象
*/
public Request<T> execute() {
Request<T> request = new HttpRequestMultipartFactory.BaseRequest();
SingletonRequestQueue.getInstance(context).add(request);
return request;
}
private class BaseRequest extends Request<T> {
public BaseRequest() {
super(method.getCode(), buildUrl(), errorListener);
if (timeoutMillis != null) {
this.setRetryPolicy(new DefaultRetryPolicy(timeoutMillis.intValue(), 1, 1));
}
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers == null ? new HashMap<>() : headers;
}
@Override
public String getBodyContentType() {
return "multipart/form-data;boundary=FILE_UPLOAD_ENTITY;";
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
String BOUNDARY="FILE_UPLOAD_ENTITY";
StringBuilder sb=new StringBuilder();
sb.append("--" + BOUNDARY + "\r\n");
/* 第二行 */
// Content-Disposition: form-data; name="参数的名称"; filename="上传的文件名" +
// "\r\n"
sb.append("Content-Disposition: form-data;");
sb.append(" name=\"");
sb.append("file");
sb.append("\"");
sb.append("; filename=\"");
sb.append(mfile.getName());
sb.append("\"");
sb.append("\r\n");
/* 第三行 */
// Content-Type: 文件的 mime 类型 + "\r\n"
sb.append("Content-Type: ");
sb.append("image/png");
sb.append("\r\n");
/* 第四行 */
// "\r\n" 空白的一行
sb.append("\r\n");
try {
bos.write(sb.toString().getBytes("utf-8"));
/* 第五行 */
// 文件的二进制数据 + "\r\n"
// bos.write(mImage.getValue());
FileInputStream inputStream =new FileInputStream(mfile);
final byte[] buffer =new byte[1024];
int len =0;
while ((len = inputStream.read(buffer)) != -1) {
Utils.log("=======>len"+len);
bos.write(buffer,0, len);
}
bos.write("\r\n".getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
/* 结尾行 */
// `"--" + BOUNDARY + "--" + "\r\n"`
String endLine = "--" + BOUNDARY + "--" + "\r\n";
try {
bos.write(endLine.toString().getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
Log.v("upLoad", "=====formImage====\n" + bos.toString());
// bos.flush();
// entity.writeTo(bos);
} catch (Exception e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
T result = parser.parse(response.data);
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
}
@Override
protected void deliverResponse(T response) {
if (successListener != null) {
successListener.onResponse(response);
}
}
}
}
09-23
01-04