200后HttpURLConnection 403响应

时间:2015-06-20 08:32:02

标签: java android https

好的,我正在开展一项有2项活动的应用程序。

让我们调用第一个出现在MainActivity顶部的LoginActivity。另外,我有一个SenderReceiver类,它扩展了AsyncTask,负责连接到我的https服务器。

我第一次从LoginActivity调用SenderReceiver,一切正常我得到200响应&我能够使用检索到的JSON。 之后,LoginActivity完成&将结果返回给MainActivity。这是我知道我已经登录的时间&我可以继续了。

现在每当我执行SenderReceiver获取其他信息时,我都会收到带有java.io.FileNotFoundException的{403}响应:https://url_of_my_server。但是,如果我再次呼叫登录,它就会起作用。

以下是连接到服务器的SenderReceiver代码段。

我还连接到iOS版app的同一台服务器&登录后从未遇到过后续通话的问题。

现在这是我第一次使用https连接&这样,我不确定它在Android上是如何工作的,所以我必须遗漏某些东西或做错事。

@Override
protected Boolean doInBackground(Object... params) {
    frag = (Fragment)params[0]; // For later
    addedParams = (List<NameValuePair>)params[1];
    postPage = (String)params[2];

    InputStream is = null;

    try {
        URL url = new URL(Constants.kWebService);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setUseCaches(false);
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(20000);
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        //conn.setDoInput(true);

        conn.setRequestProperty("CONTENT_TYPE", "application/json");
        conn.setRequestProperty("X-requested-with", "XMLHttpRequest");

        String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
        conn.setRequestProperty("Authorization", base64EncodedCredentials);

        String param = "page="+postPage+"&";
        for(int i = 0; i < addedParams.size(); i++) {
            String and = (i < addedParams.size()-1)? "&": "";
            param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
        }
        conn.setFixedLengthStreamingMode(param.getBytes().length);

        PrintWriter out = new PrintWriter(conn.getOutputStream());
        out.print(param);
        out.close();

        // Starts the query
        conn.connect();
        int responseCode = conn.getResponseCode();
        is = conn.getInputStream();

        // Convert the InputStream into a string
        responseSTR = Constants.inputStreamToString(is).toString();
        return true;
        // Makes sure that the InputStream is closed after the app is
        // finished using it.
    } catch (ProtocolException pe) {
        Constants.Log("Protocol Exception:"+pe.getMessage());
    } catch (IOException io) {
        Constants.Log("IO Exception:"+io.getMessage());
        io.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException io) {
                Constants.Log("is.close IO Exception:"+io.getMessage());
            }
        }
    }
    return false;
}

1 个答案:

答案 0 :(得分:0)

修正了它!

我所要做的就是设置cookie标题:

conn.setRequestProperty("Cookie", Constants.kCookies);

&安培;在响应之后检索该cookie以便将其设置为:

List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
    Constants.kCookies = cookies.get(0);
}

这种方式在最初的HttpURLConnection连接(即:登录)中,cookie是空的&amp;不需要。一旦连接成功(“登录”之后),它就会收到cookie&amp;设置它。

之后,任何后续连接都会将该cookie作为标题的一部分发送。

以下更新方法:

@Override
protected Boolean doInBackground(Object... params) {
    frag = (Fragment)params[0];
    addedParams = (List<NameValuePair>)params[1];
    postPage = (String)params[2];

    InputStream is = null;

    try {
        URL url = new URL(Constants.kWebService);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setUseCaches(false);
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(20000);
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        //conn.setDoInput(true);

        conn.setRequestProperty("CONTENT_TYPE", "application/json");
        conn.setRequestProperty("X-requested-with", "XMLHttpRequest");

        String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
        conn.setRequestProperty("Authorization", base64EncodedCredentials);

        // Get the cookie from my Constants file & set it, Constants.kCookies is a static String
        conn.setRequestProperty("Cookie", Constants.kCookies);

        String param = "page="+postPage+"&";
        for(int i = 0; i < addedParams.size(); i++) {
            String and = (i < addedParams.size()-1)? "&": "";
            param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
        }
        conn.setFixedLengthStreamingMode(param.getBytes().length);

        PrintWriter out = new PrintWriter(conn.getOutputStream());
        out.print(param);
        out.close();

        // Starts the query
        conn.connect();
        int responseCode = conn.getResponseCode();
        Constants.Log("The response code is: " + responseCode);
        is = conn.getInputStream();

        // Retrieve the cookie from the response & if not null save it to Constants.kCookies
        List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
        if(cookies != null) {
            Constants.kCookies = cookies.get(0);
        }

        // Convert the InputStream into a string
        responseSTR = Constants.inputStreamToString(is).toString();//readIt(is, len);
        return true;
        // Makes sure that the InputStream is closed after the app is
        // finished using it.
    } catch (ProtocolException pe) {
        Constants.Log("Protocol Exception:"+pe.getMessage());
    } catch (IOException io) {
        Constants.Log("IO Exception:"+io.getMessage());
        io.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException io) {
                Constants.Log("is.close IO Exception:"+io.getMessage());
            }
        }
    }

    return false;
}