我正在尝试从服务器下载文件。如果我通过浏览器发出此请求,则会得到所需的文件,但是当我使用volley时,我在使用setRetryPolicy后首先得到com.android.volley.TimeoutError,我得到
BasicNetwork.performRequest: Unexpected response code 200
这是我上课的人:
public class DefexConnection implements Response.Listener<byte[]>, Response.ErrorListener {
private Context ctx;
private DefexDownload download;
public DefexConnection(Context ctx){
this.ctx = ctx;
}
public void download(String link, final HashMap<String, String> params){
DefexDownload req = new DefexDownload(Request.Method.GET, link, DefexConnection.this, DefexConnection.this, params);
req.setRetryPolicy(new DefaultRetryPolicy( 500000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue queue = Volley.newRequestQueue(this.ctx, new HurlStack(null, getSocketFactory()));
queue.add(req);
}
private SSLSocketFactory getSocketFactory() {
CertificateFactory cf = null;
try {
cf = CertificateFactory.getInstance("X.509");
InputStream caInput = ctx.getResources().openRawResource(R.raw.comodoroca);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.e("CERT", "ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
Log.d("CipherUsed", session.getCipherSuite());
return hostname.compareTo("www.defexsecurity.com")==0;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
SSLContext context = null;
context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
SSLSocketFactory sf = context.getSocketFactory();
return sf;
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
@Override
public void onResponse(byte[] response) {
HashMap<String, Object> map = new HashMap<String, Object>();
int count;
if (response!=null) {
String content = download.responseHeaders.get("Content-Disposition").toString();
StringTokenizer st = new StringTokenizer(content, "=");
String[] arrTag = st.toArray();
String filename = arrTag[1];
filename = filename.replace(":", ".");
Log.d("DEBUG::RESUME FILE NAME", filename);
try{
long lenghtOfFile = response.length;
//covert reponse to input stream
InputStream input = new ByteArrayInputStream(response);
File path = Environment.getExternalStorageDirectory();
File file = new File(path, filename);
map.put("resume_path", file.toString());
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file));
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
Log.e("DEFEX","file saved to "+file.getAbsolutePath());
}catch(IOException e){
e.printStackTrace();
}
}
}
@Override
public void onErrorResponse(VolleyError error) {
Log.e("DEFEX", "UNABLE TO DOWNLOAD FILE. ERROR:: "+error.toString());
}
}
这是我的类DefexDownload(扩展了Request):
class DefexDownload extends Request<byte[]>{
private final Response.Listener<byte[]> mListener;
private Map<String, String> mParams;
public Map<String, String> responseHeaders ;
DefexDownload(int post, String mUrl, Response.Listener<byte[]> listener, Response.ErrorListener errorListener, HashMap<String, String> params){
super(post, mUrl, errorListener);
setShouldCache(false);
mListener = listener;
mParams=params;
}
@Override
protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
return mParams;
}
@Override
protected void deliverResponse(byte[] response) {
mListener.onResponse(response);
}
@Override
protected Response<byte[]> parseNetworkResponse(NetworkResponse response) {
//Initialise local responseHeaders map with response headers received
responseHeaders = response.headers;
//Pass the response data here
return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response));
}
}
我不知道这里可能出什么问题,将不胜感激任何帮助
编辑:我在此处找到的所有其他答案中,问题似乎出在代理或设备仿真器上,但是我正在不使用任何代理的真实设备上运行我的应用
答案 0 :(得分:0)
根据Github上的issue。
所以
HurlStack
或多或少只是薄薄的包装HttpUrlConnection
。EOFException
大概是从那里来的 尝试建立连接时。我认为没有太多 Volley可以做到这一点,如果没有安全的解决方法, 有一个已知的平台错误。原因链的堆栈跟踪很容易看,因为 某些平台类在幕后引发了异常。 否则,我怀疑如果您只是重现同样的问题 直接使用了
HttpUrlConnection
,这意味着不幸的是没有 凌空可以做很多事情。搜索异常表明许多潜在问题 如 Android HttpUrlConnection Url doesn't work on emulator 指出相关机器上的网络问题 解释了为什么它只是模拟器。
问题的预期:
解决方案
答案 1 :(得分:0)
我无法使用Volley做到这一点,但是我可以使用此answer成功下载文件(最有效的解决方案是接受的答案中的解决方案2)