与Volley一起下载给出错误:意外响应代码200

时间:2018-08-12 21:15:43

标签: java android android-volley

我正在尝试从服务器下载文件。如果我通过浏览器发出此请求,则会得到所需的文件,但是当我使用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));
    }

}

我不知道这里可能出什么问题,将不胜感激任何帮助

编辑:我在此处找到的所有其他答案中,问题似乎出在代理或设备仿真器上,但是我正在不使用任何代理的真实设备上运行我的应用

2 个答案:

答案 0 :(得分:0)

根据Github上的issue

  

所以HurlStack或多或少只是薄薄的包装   HttpUrlConnectionEOFException大概是从那里来的   尝试建立连接时。我认为没有太多   Volley可以做到这一点,如果没有安全的解决方法,   有一个已知的平台错误。

     

原因链的堆栈跟踪很容易看,因为   某些平台类在幕后引发了异常。   否则,我怀疑如果您只是重现同样的问题   直接使用了HttpUrlConnection,这意味着不幸的是没有   凌空可以做很多事情。

     

搜索异常表明许多潜在问题   如   Android HttpUrlConnection Url doesn't work on emulator   指出相关机器上的网络问题   解释了为什么它只是模拟器。

问题的预期:

  • 仿真器连接配置不正确
  • 主机PC防病毒或防火墙。

解决方案

  • 使用真实设备尝试代码。
  • 在使用主机PC配置网络并停止防病毒 或/和 防火墙后,尝试使用仿真器。

答案 1 :(得分:0)

我无法使用Volley做到这一点,但是我可以使用此answer成功下载文件(最有效的解决方案是接受的答案中的解决方案2)