Android:HttpClient、tomcat支援php、搭建PHP後臺
目的: 建立一個簡單的Android專案,並搭建PHP後臺,實現Android與PHP之間的通訊。 本地環境: Android Studio3.1.2 Tomcat 7.0.63
一、建立一個簡單的安卓專案
File->New->New project,寫好專案名稱,選擇好本地儲存路徑後,一直NEXT就可以創建出一個專案。
二、Http Client
java中要傳送http請求可通過Http Client實現。接下來是封裝httpclient的get()和post()。下面是個人第一次在網上查閱後嘗試寫的,有些地方可能寫得不好,見諒哈,小白一隻。
1、新建HttpClient類
package com.example.zwl.myapplication;
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
public class HttpClient {
private String Url;
private int timeout;
public String getUrl() {
return Url;
}
public void setUrl(String url) {
this.Url = url;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int time) {
this.timeout = time;
}
public HashMap<String, Object> get() {
//get請求:存放狀態碼和請求內容
HashMap<String, Object> result = null;
//用於存放http狀態碼
int STATUS;
try {
//建立URL物件
URL geturl = new URL(Url);
HttpURLConnection httpURLConnection = (HttpURLConnection) geturl.openConnection();
//設定連線超時(ms)
httpURLConnection.setConnectTimeout(timeout);
//設定請求方式(預設為get)
httpURLConnection.setRequestMethod("GET");
//建立到遠端物件的實際連線
httpURLConnection.connect();
//獲取狀態碼
STATUS = httpURLConnection.getResponseCode();
//返回開啟連線讀取的輸入流,輸入流轉化為StringBuffer型別
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
//轉化為utf-8的編碼格式
line = new String(line.getBytes("utf-8"));
stringBuffer.append(line);
}
bufferedReader.close();
httpURLConnection.disconnect();
result = new HashMap<>();
result.put("status", STATUS);
result.put("data", stringBuffer.toString());
} catch (MalformedURLException e) {
Log.d("get", "build url failed");
e.printStackTrace();
} catch (IOException e) {
Log.d("get", "build failed");
e.printStackTrace();
}
return result;
}
public HashMap<String, Object> post(HashMap<String, String> param) {
HashMap result = null;
try {
URL posturl = new URL(Url);
HttpURLConnection httpURLConnection = (HttpURLConnection) posturl.openConnection();
httpURLConnection.setConnectTimeout(timeout);
httpURLConnection.setRequestMethod("POST");
//設定是否向httpURLConnection輸出
httpURLConnection.setDoOutput(true);
//設定是否從httpURLConnection讀入
httpURLConnection.setDoInput(true);
//POST不能使用快取
httpURLConnection.setUseCaches(false);
httpURLConnection.setInstanceFollowRedirects(true);
//設定請求頭
httpURLConnection.setRequestProperty("Charset", "utf-8");
httpURLConnection.setRequestProperty("contentType", "utf-8");
httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
httpURLConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
//配置需在連線之前完成
httpURLConnection.connect();
//設定請求內容
DataOutputStream out = new DataOutputStream(httpURLConnection.getOutputStream());
String content = "";
//遍歷Map,構造表單引數
//keySet()返回postcontent內所有的關鍵字
for (String key : param.keySet()) {
String value = param.get(key);
content += key + "=" + URLEncoder.encode(value, "utf-8") + "&";
}
if (!content.isEmpty()) {
content = content.substring(0, content.length() - 1);
}
out.writeBytes(content);
out.flush();
out.close();
int code = httpURLConnection.getResponseCode();
Log.d("post", "content:" + content);
Log.d("post", "out:" + out);
//返回開啟連線讀取的輸入流,輸入流轉化為StringBuffer型別
//BufferedReader提供通用的緩衝方式文字讀取
//InputStreamReader()能將位元組流輸出為字元流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
String line;
StringBuffer stringBuffer = new StringBuffer();
while ((line = bufferedReader.readLine()) != null) {
line = new String(line.getBytes("utf-8"));
// Log.d(tag:"post",line);
stringBuffer.append(line);
}
Log.d("post", "data : " + stringBuffer.toString());
bufferedReader.close();
httpURLConnection.disconnect();
result = new HashMap<>();
result.put("status", code);
result.put("data", stringBuffer.toString());
} catch (MalformedURLException e) {
Log.d("post", "build url failed");
e.printStackTrace();
} catch (IOException e) {
Log.d("post", "build failed");
e.printStackTrace();
}
return result;
}
}
2、實現了HttpClient類後就是如何使用這個類來進行http請求。由於android4.0以後不能在主執行緒發起網路請求,所以這裡需要建立一個執行緒用於進行網路請求。 我這裡直接在MainActivity.java中建立執行緒。同時在類MyThread中重寫run()。 這裡貼的是傳送post請求的程式碼。
package com.example.zwl.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//建立新執行緒
MyThread t = new MyThread();
/* 啟動執行緒 */
t.start();
}
}
package com.example.zwl.myapplication;
import android.util.Log;
import java.util.HashMap;
public class MyThread extends Thread{
@Override
public void run(){
super.run();
HttpClient http = new HttpClient();
//此處ip為自己電腦的ip地址
http.setUrl("http://10.201.220.149:8080/phpbin/index.php");
http.setTimeout(10000);
HashMap<String, String> params = new HashMap<String, String>();
params.put("test","test");
HashMap<String,Object> result = http.post(params);
Object code = result.get("status");
Object data = result.get("data");
Log.v("post","post資料"+String.valueOf(code));
Log.v("post","post資料"+String.valueOf(data));
}
}
這裡可以測試一下,編寫的程式是否可用。為了測試,我將 MyThread類中的run()改成下面這樣,這裡是傳送get請求的程式碼:
package com.example.zwl.myapplication;
import android.util.Log;
import java.util.HashMap;
public class MyThread extends Thread{
@Override
public void run(){
super.run();
HttpClient http = new HttpClient();
http.setUrl("https://www.baidu.com");
http.setTimeout(10000);
HashMap<String,Object> result = http.get();
Object code = result.get("status");
Object data = result.get("data");
Log.v("get","get資料"+String.valueOf(code));
Log.v("get","get資料"+String.valueOf(data));
}
}
記得配置一下聯網許可權,在AndroidManifest.xml檔案中:
執行一下程式:Build -> Buid APK(s),Run ‘app’。
從列印的資料來看,請求成功了。
3、檢視本機ip
win+r,輸入cmd,輸入ipconfig即可看到本機ip。
三、搭建本地PHP伺服器
1、tomcat下載 這裡選擇壓縮包解壓。將壓縮包解壓在自己想要放置的資料夾下,環境配置方面需要在系統環境變數中新建JAVA_HOME變數,其值為本機jdk的安裝目錄。 檢視apache-tomcat-7.0.63\bin目錄下catalina.bat檔案 出現這個代表tomcat安裝成功。雙擊apache-tomcat-7.0.63\bin目錄下startup.bat檔案。瀏覽器:localhost:8080訪問。 假如雙擊startup.bat出現閃退,可編輯startup.bat檔案,在末尾加上PAUSE,再次啟動,根據資訊進行除錯。
2、tomcat登陸
開啟apache-tomcat-7.0.63\webapps\host-manager\WEB-INF下的web.xml檔案。 找到admin-gui,複製紅框內容,增加管理角色manager-gui 開啟conf/tomcat-users.xml。 目的是為了建立一個使用者名稱和密碼均為tomcat的使用者,此使用者擁有管理員許可權。manager-gui是管理者角色,對於tomcat6,mangaer是管理者角色,不是manager-gui。 重啟tomcat之後再次輸入localhost:8080,點選server status,輸入tomcat,密碼為tomcat,即可登陸。
3、配置tomcat支援php執行。
下載好php壓縮包後解壓至apache-tomcat-7.0.63(tomcat安裝目錄)下,進入php目錄。 支援php cgi執行,修改php.ini如下:
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
; extension_dir = "./"
extension_dir = "ext"
; On windows:
cgi.force_redirect = 0
; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
; sys_temp_dir = "/tmp"
開啟apache-tomcat-7.0.63\conf\context.xml,修改如下:
<!-- The contents of this file will be loaded for each web application -->
<Context privileged = "true" >
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>php</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
<init-param>
<param-name>clientInputTimeout</param-name>
<param-value>200</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>executable</param-name>
<!-- tomcat安裝目錄下php下的php-cgi.exe -->
<param-value>C:\apache-tomcat-7.0.63\php7.1.9\php-cgi.exe</param-value>
</init-param>
<init-param>
<param-name>passShellEnvironment</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cgiPathPrefix</param-name>
<!--指定php在apache-tomcat-7.0.63\webapps\ROOT\WEB-INF\phpbin下-->
<param-value>WEB-INF/phpbin</param-value>
</init-param>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>php</servlet-name>
<url-pattern>/phpbin/*</url-pattern>
</servlet-mapping>
重啟tomcat,在apache-tomcat-7.0.63\webapps\ROOT\WEB-INF在新建phpbin,新建index.php,內容如下:
<?php phpinfo() ?>
訪問:localhost:8080/phpbin/index.php,看到下面,搭建成功。
4、手機訪問本地伺服器
保證手機與電腦連線在同一wifi下,使用手機瀏覽器訪問:http://ip(電腦ip):8080即可訪問到tomcat主頁
四、php與android間的互動
通過上面步驟,Android端已經可以傳送請求,設定url為自己本機ip+php檔案路徑,就可以向php檔案傳送post請求。這裡貼一下php檔案的程式碼。
<?php
//定義返回資料
$data = ["code" => "","msg" => ""];
if (!empty($_POST)) {
//
foreach($_POST as $key=>$value){
//接收資料的鍵對值
$data = ["code" => $key,"msg" => $value]; //因為post資料只有一對鍵對值,這裡我偷懶直接把返回資料在此迴圈裡填裝
};
}
echo json_encode($data);
?>
注意:
- 在執行前記得開啟本地tomcat
php檔案中echo、var_dump資料將顯示在android端。通過網頁訪問php檔案看不到資料。
執行: php成功返回資料給android端。