HttpURLConnection 在這請求方式是Java包中的;
AndroidManifest.xml配置權限:
<!-- 訪問網絡是危險的行為 所以需要權限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 設置壁紙是危險的行為 所以需要權限 --> <uses-permission android:name="android.permission.SET_WALLPAPER" />
MainActivity7.java :
package liudeli.async; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; public class MainActivity7 extends Activity implements View.OnClickListener { private EditText etName; private EditText etPwd; private Button btLogin; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main7); etName = findViewById(R.id.et_name); etPwd = findViewById(R.id.et_pwd); btLogin = findViewById(R.id.bt_login); btLogin.setOnClickListener(this); } // 請求服務器的地址 private final String PATH = "http://127.0.0.1:8080/LoginServlet"; @Override public void onClick(View v) { // 拼裝參數 final Map<String, String> map = new HashMap<>(); map.put("name", etName.getText().toString()); map.put("pwd", etPwd.getText().toString()); // 聯網操作必須開啟線程,執行異步任務 new Thread(){ @Override public void run() { super.run(); try { // Get請求方式,參數操作是拼接在鏈接 loginByGet(PATH, map); // Post請求方式,參數操作是封裝實體對象 loginByPost(PATH, map); } catch (Exception e) { e.printStackTrace(); threadRunToToast("登錄是程序發生異常"); } } }.start(); } /** * HttpURLConnection Get 方式請求 * @param path 請求的路徑 * @param map 請求的參數 * 拼接后的完整路徑:http://127.0.0.1:8080/LoginServlet?name=zhangsan&pwd=123456 */ private void loginByGet(String path, Map<String, String> map) throws Exception{ // 拼接路徑地址 拼接后的完整路徑:http://127.0.0.1:8080/LoginServlet?name=zhangsan&pwd=123456 StringBuffer pathString = new StringBuffer(path); pathString.append("?"); // 迭代遍歷Map for (Map.Entry<String, String> mapItem : map.entrySet()) { String key = mapItem.getKey(); String value = mapItem.getValue(); // name=zhangsan& pathString.append(key).append("=").append(value).append("&"); } // name=zhangsan&pwd=123456& 刪除最后一個符號& 刪除后:name=zhangsan&pwd=123456 pathString.deleteCharAt(pathString.length() - 1); // 最后完整路徑地址是:http://127.0.0.1:8080/LoginServlet?name=zhangsan&pwd=123456 // 第一步 包裝網絡地址 URL url = new URL(pathString.toString()); // 第二步 打開連接對象 HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); // 第三步 設置連接超時時長 httpURLConnection.setConnectTimeout(5000); // 第四步 設置請求方式Get httpURLConnection.setRequestMethod("GET"); // 第五步 發生請求 ⚠注意:只有在>>httpURLConnection.getResponseCode(); 才向服務器發請求 int responseCode = httpURLConnection.getResponseCode(); // 第六步 判斷請求碼是否成功 // 注意⚠️:只有在執行conn.getResponseCode() 的時候才開始向服務器發送請求 if(responseCode == HttpURLConnection.HTTP_OK) { // 第七步 獲取服務器響應的流 InputStream inputStream = httpURLConnection.getInputStream(); byte[] bytes = new byte[1024]; int len = 0; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while (-1 != (len = inputStream.read())) { // 把存取到bytes的數據,寫入到>>ByteArrayOutputStream bos.write(bytes, 0, len); } // 第六步 判斷是否請求成功, 注意:⚠️ success 是自定義服務器返回的 success代表登錄成功 String loginResult = bos.toString(); if ("success".equals(loginResult)) { // 不能子在子線程中Toast // Toast.makeText(this, "登錄成功", Toast.LENGTH_SHORT).show(); threadRunToToast("登錄成功"); } else { // 不能子在子線程中Toast // Toast.makeText(this, "登錄失敗", Toast.LENGTH_SHORT).show(); threadRunToToast("登錄失敗"); } // 第七步 關閉流 inputStream.close(); bos.close(); } else { // 不能子在子線程中Toast // Toast.makeText(this, "登錄失敗,請檢查網絡!", Toast.LENGTH_SHORT).show(); threadRunToToast("登錄失敗,請檢查網絡!"); } } /** * HttpURLConnection Get 方式請求 * @param path 請求的路徑 * @param params 請求的參數 * 路徑:http://127.0.0.1:8080/LoginServlet * * 參數: * name=zhangsan * pwd=123456 */ private void loginByPost(String path, Map<String, String> params) throws Exception { // ------------------------------------------------ 以下是實體拼接幫助 /** * 拼實體 注意⚠️:是需要服務器怎么配置 這里就要怎么拼接 例如:user.name=zhangsan&user.pwd=123 * 注意:⚠ 這不是訪問服務器的地址,這是拼接實體 */ StringBuilder paramsString = new StringBuilder(); for(Map.Entry<String, String> entry: params.entrySet()){ paramsString.append(entry.getKey()); paramsString.append("="); paramsString.append(URLEncoder.encode(entry.getValue(), "UTF-8")); paramsString.append("&"); } /** * user.name=zhangsan&user.pwd=123& 刪除最后一個符號& 刪除后:user.name=zhangsan&user.pwd=123 * 注意:⚠ 這不是訪問服務器的地址,這是拼接實體 */ paramsString.deleteCharAt(paramsString.length() - 1); // 理解為實體 byte[] entity = paramsString.toString().getBytes(); // ------------------------------------------------ 以下是 HttpURLConnection Post 訪問 代碼 // 第一步 包裝網絡地址 URL url = new URL(path); // 第二步 打開連接對象 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 第三步 設置連接超時時長 conn.setConnectTimeout(5000); // 第四步 設置請求方式 POST conn.setRequestMethod("POST"); /** * 第五步 設置請求參數 * 請求參數類型 */ conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // 請求實體的長度(字節) conn.setRequestProperty("Content-Length", entity.length+""); // 第六步 允許對外輸出 conn.setDoOutput(true); // 第七步 得到輸出流 並把實體輸出寫出去 OutputStream os = conn.getOutputStream(); os.write(entity); // 注意⚠️:只有在執行conn.getResponseCode() 的時候才開始向服務器發送請求 if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){ // 第八步 獲取服務器響應的流 InputStream inputStream = conn.getInputStream(); byte[] bytes = new byte[1024]; int len = 0; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while (-1 != (len = inputStream.read())) { // 把存取到bytes的數據,寫入到>>ByteArrayOutputStream bos.write(bytes, 0, len); } // 第九步 判斷是否請求成功, 注意:⚠️ success 是自定義服務器返回的 success代表登錄成功 String loginResult = bos.toString(); if ("success".equals(loginResult)) { // 不能子在子線程中Toast // Toast.makeText(this, "登錄成功", Toast.LENGTH_SHORT).show(); threadRunToToast("登錄成功"); } else { // 不能子在子線程中Toast // Toast.makeText(this, "登錄失敗", Toast.LENGTH_SHORT).show(); threadRunToToast("登錄失敗"); } // 第十步 關閉流 inputStream.close(); bos.close(); } } /** * 在 主線程 子線程 中提示,屬於UI操作 */ private void threadRunToToast(final String text) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show(); } }); } }
activity_main7.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名" /> <EditText android:id="@+id/et_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密碼" /> <EditText android:id="@+id/et_pwd" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> <Button android:id="@+id/bt_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="20dp" android:text="login" /> </LinearLayout>