不推荐使用DefaultHttpClient和HttpPost,使用HttpURLConnection POST但获取错误:错误的参数

时间:2015-07-27 18:00:41

标签: android httpurlconnection

现在我正在与HttpURLConnection班级作战。早些时候我只是这样做了:

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params, "utf-8"));

HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();

return httpEntity.getContent();

但由于几乎所有内容都被弃用,我决定改变这一点。我尝试用以下代码替换它:

/**
 * 
 * @param urlString
 * @param params
 * @return
 * @throws IOException
 */
public InputStream getStreamFromConnection(String urlString, ContentValues params) throws IOException {
    HttpURLConnection connection = null;

    if(ConnectionDetector.isConnectedToInternet(this.context)) {
        try {
            StringBuilder urlBuilder = new StringBuilder(urlString);
            StringBuilder paramsBuilder = new StringBuilder();

            int i = 0;

            for (String key : params.keySet()) {
                paramsBuilder.append((i == 0 ? "" : "&") + key + "=" + URLEncoder.encode(params.get(key).toString(), "utf8"));
                i++;
            }

            Log.v("Connection", "This is my URL: " + urlBuilder.toString());

            URL url = new URL(urlBuilder.toString());

            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setReadTimeout(10000);
            connection.setConnectTimeout(15000);
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setChunkedStreamingMode(0);

            Log.v("Connection", "These are my Params: " + paramsBuilder.toString());

            DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
            outputStream.write(paramsBuilder.toString().getBytes());
            outputStream.flush();
            outputStream.close();

            return connection.getInputStream();
        } finally {
            if(connection != null) {
                connection.disconnect();
            }
        }
    } else {
        return null;
    }
}

但是现在我总是从服务器得到我的参数错误的消息。我的新代码与旧代码完全相同吗? 我的参数有什么问题?是否有一个函数,以便我可以看到发送到服务器的整个url字符串?

8366-8599/de.myPackage.myApp V/Connection﹕ This is my URL: http://myUrl.com/mobile_login.php
8366-8599/de.myPackage.myApp V/Connection﹕ These are my Params: email=my%40email.com&password=B5FDA3381CDE21D59843ACC16572127F45078770A331D9BE9085719A5BD35ACF46D&login_request=1
8366-8599/de.myPackage.myApp V/Connection﹕ ERROR: WRONG PARAMETERS
8366-8599/de.myPackage.myApp V/JSONParser﹕ [ 07-27 20:18:39.469  8366: 8599 V/JSONParser ]

1 个答案:

答案 0 :(得分:3)

很难确切地说出代码中出现了什么问题,但我只是使用emailpasswordlogin_request参数来处理这个简单示例。< / p>

首先,这是使用HttpURLConnection的方法:

public JSONObject makeHttpRequest(String url,
                                  HashMap<String, String> params) {

    StringBuilder sbParams = new StringBuilder();
    StringBuilder result = new StringBuilder();
    String charset = "UTF-8";
    HttpURLConnection conn = null;
    JSONObject jObj = null;
    URL urlObj = null;
    DataOutputStream wr = null;

    int i = 0;
    for (String key : params.keySet()) {
        try {
            if (i != 0){
                sbParams.append("&");
            }
            sbParams.append(key).append("=")
                    .append(URLEncoder.encode(params.get(key), charset));

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        i++;
    }

    Log.d("HTTP Request", "params: " + sbParams.toString());

    try {
        urlObj = new URL(url);

        conn = (HttpURLConnection) urlObj.openConnection();

        conn.setDoOutput(true);

        conn.setRequestMethod("POST");

        conn.setRequestProperty("Accept-Charset", charset);

        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);

        conn.connect();

        String paramsString = sbParams.toString();

        wr = new DataOutputStream(conn.getOutputStream());
        wr.writeBytes(paramsString);
        wr.flush();
        wr.close();

    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        //Receive the response from the server
        InputStream in = new BufferedInputStream(conn.getInputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));

        String line;
        while ((line = reader.readLine()) != null) {
            result.append(line);
        }

        Log.d("HTTP Request", "result: " + result.toString());

    } catch (IOException e) {
        e.printStackTrace();
    }

    conn.disconnect();

    // try parse the string to a JSON object
    try {
        jObj = new JSONObject(result.toString());
    } catch (JSONException e) {
        Log.e("HTTP Request", "Error parsing data " + e.toString());
    }

    // return JSON Object
    return jObj;
}

这是我用于测试上述方法的AsyncTask:

class PostAsyncTest extends AsyncTask<String, String, JSONObject> {

    private ProgressDialog pDialog;

    private static final String LOGIN_URL = "http://www.example.com/testPost.php";

    private static final String TAG_SUCCESS = "success";
    private static final String TAG_MESSAGE = "message";


    @Override
    protected void onPreExecute() {
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Attempting login...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected JSONObject doInBackground(String... args) {

        try {
            HashMap<String, String> params = new HashMap<>();
            params.put("email", args[0]);
            params.put("password", args[1]);
            params.put("login_request", args[2]);

            JSONObject json = makeHttpRequest(
                    LOGIN_URL, params);

            if (json != null) {
                Log.d("HTTP Async", "JSON result: " + json.toString());

                return json;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(JSONObject json) {

        int success = 0;
        String message = "";

        if (pDialog != null && pDialog.isShowing()) {
            pDialog.dismiss();
        }

        if (json != null) {
            Toast.makeText(MainActivity.this, json.toString(),
                    Toast.LENGTH_LONG).show();

            try {
                success = json.getInt(TAG_SUCCESS);
                message = json.getString(TAG_MESSAGE);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        if (success == 1) {
            Log.d("HTTP Async", "Success! " +  message);
        }else{
            Log.d("HTTP Async", "Failure " + message);
        }
    }

}

这是我执行AsyncTask的方式:

    String email = "my_email@example.com";
    String password = "myPasswordIsVery5ecur3";
    String loginRequest = "1";
    new PostAsyncTest().execute(email, password, loginRequest);

以下是我用来测试的简单PHP代码:

<?php

  // array for JSON response
$response = array();

// check for required fields
if (isset($_POST['email']) && isset($_POST['password']) && isset($_POST['login_request'])) {

    $name = $_POST['email'];
    $message = $_POST['password'];
    $loginrequest = $_POST['login_request'];

    $response["success"] = 1;
    $response["message"] = "Login successful.";

    // echoing JSON response
    print(json_encode($response));


 } else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) missing";

    // echoing JSON response
    print(json_encode($response));
}
?> 

结果:

 D/HTTP Request﹕ params: password=myPasswordIsVery5ecur3&email=my_email%40example.com&login_request=1
 D/HTTP Request﹕ result: {"success":1,"message":"Login successful."}
 D/HTTP Async﹕ JSON result: {"message":"Login successful.","success":1}
 D/HTTP Async﹕ Success! Login successful.