1.准备工作
1.1.安装使用Apache
Apache下载、解压https://httpd.apache.org
1.2.Apache配置(httpd.conf)(路径\Apache24\conf) 安装路径Define SRVROOT "D:\Program Files\Apache24"(改你自己的路径) 访问端口Listen 8686
1.3.Apache服务安装、启动
管理员身份运行cmd 进入Apache的bin目录cd /e E:\Apache24\Apache24\bin(注意管理员身份进入目录,如果没进入就在cd后加个/d)
安装命令:httpd -k install
httpd -k install
1.4搜索-服务-服务(本地)-启动-Apache2.4
1.5.Apache访问
搜索-启用或关闭Windows功能
最后勾选两个文件(注意:勾选时要将所有的子文件一同勾选,否则会显示和上方文件相同的-而不是√),然后点击确定即可。
1.6 Apache访问http://localhost:8686的实现
我们在E:\Apache24\Apache24\htdocs新建一个json文件,文件名get_data .json,然后在里面写入json数据,我用的是vscode来写。
{
"MSG": "OK",
"Persons_Detail": [
{
"id": "001",
"name": "老葛",
"height": "180cm"
},
{
"id": "002",
"name": "老张",
"height": "170cm"
},
{
"id": "003",
"name": "小王",
"height": "177cm"
}
]
}
1.7.写完之后,我们就可以对 Apache进行访问http://127.0.0.1:8686/get_data.json
2.在android studio对 Apache进行访问前代码实现准备
2.1 在build.gradle添加gson的依赖
implementation 'com.squareup.okhttp3:okhttp:4.1.0'
implementation 'com.google.code.gson:gson:2.9.0'
点右上角Sync now
2.2 添加插件Gsonformat
准备工作做好后,就可以开始布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="个人信息" />
<TextView
android:id="@+id/persons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="无" />
<Button
android:id="@+id/get_persons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="获取" />
</LinearLayout>
创建一个Persons类,双击打开Persons类,在空白处右键,找到生成选项
点击生成选项,弹出生成菜单,点击Gsonformat选项
输入以下Json数据,包括2个字段,第一个是调用反馈字段,第二个是个人详细信息字段(当你点击Format按钮,能自动格式化Json数据时候,表示Json数据无异常
点击ok,插件自动生成Persons实体类的具体字段,结果如下
请求方法sendRequest
解析方法parseJsonWithGSON
3.实现方法
3.1导入类
在 MainActivity.java 文件中导入需要用到的类:
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.Gson;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
2.2 设置布局和控件
在 onCreate() 函数中设置布局文件,并获取布局文件中的控件:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取布局文件中的控件
mPersons = findViewById(R.id.persons);
mGetPersons = findViewById(R.id.get_persons);
// 设置点击事件监听器
mGetPersons.setOnClickListener(this);
// 初始化回调对象
initData();
}
其中,mPersons
是一个 TextView,用于显示网络请求结果;mGetPersons
是一个 Button,用于触发网络请求。通过 findViewById()
方法获取这两个控件。
2.3 定义回调函数
初始化回调函数 ok3cb
,当网络请求成功或失败时,系统会自动调用回调函数中的方法:
// 初始化回调函数,该函数会在网络请求的响应成功或失败时被调用
private void initData() {
ok3cb = new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
// 在请求出错时执行的代码可以在这里编写
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
// 处理网络响应结果,此处为异步更新 UI 的示例
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
parseJsonWithGson(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
};
}
其中,onFailure()
方法是在网络请求失败时调用的方法;onResponse()
方法是在网络请求成功时调用的方法。在 onResponse()
方法中调用了 parseJsonWithGson()
方法,将 JSON 字符串解析为 Java 对象,并显示在 UI 中。
2.4 实现点击事件
// 设置点击事件的回调函数
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.get_persons:
// 发送网络请求,获取 JSON 数据
sendRequest();
break;
}
}
在 sendRequest()
函数中构建并发送网络请求
// 发送 HTTP POST 请求,获取 JSON 数据
private void sendRequest() {
// 定义请求 URL(这里用了模拟器访问本机 localhost 的地址)
String url = "http://10.0.2.2:8686/get_data.json";
// 定义需要传递的 JSON 数据
String json = "{\"id\": \"001\"}";
// 创建 OkHttpClient 对象
OkHttpClient client = new OkHttpClient();
// 定义请求体和请求对象
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
RequestBody body = RequestBody.create(json, mediaType);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
// 异步发送网络请求,并在响应成功或失败时回调 ok3cb 函数,通知应用程序处理结果
client.newCall(request).enqueue(ok3cb);
}
在 sendRequest() 函数中,我们定义了一个 URL,服务器会对这个请求进行响应。然后,我们定义了一个需要传递的 JSON 数据,即向服务器发送的数据。接下来,我们使用 OkHttp 库中提供的 OkHttpClient 对象创建网络连接。
然后,我们设置请求头的信息及上传的具体数据,并通过 Request 对象将其打包到一起。
最后,我们通过调用 OkHttpClient 对象的 newCall()
方法,将 request
带入该函数中,实现异步请求。同时,我们将回调函数 ok3cb
传递给 enqueue
函数,在请求完成时自动回调,通知我们响应已经到达。经过这些步骤之后,我们的请求就完成了。
以下是完整的代码
package com.example.test;
// 导入需要用到的类
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.Gson;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mPersons;
private Button mGetPersons;
private okhttp3.Callback ok3cb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取布局文件中的控件
mPersons = findViewById(R.id.persons);
mGetPersons = findViewById(R.id.get_persons);
// 设置点击事件监听器
mGetPersons.setOnClickListener(this);
// 初始化回调对象
initData();
}
// 初始化回调函数,该函数会在网络请求的响应成功或失败时被调用
private void initData() {
ok3cb = new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
// 在请求出错时执行的代码可以在这里编写
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
// 处理网络响应结果,此处为异步更新 UI 的示例
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
parseJsonWithGson(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
};
}
// 设置点击事件的回调函数
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.get_persons:
// 发送网络请求,获取 JSON 数据
sendRequest();
break;
}
}
// 将 JSON 字符串解析为 Java 对象,并显示在 UI 中
private void parseJsonWithGson(String strJSONData) {
String ps = "";
Gson mGson = new Gson();
// 将 JSON 解析为 Persons 对象
Persons persons = mGson.fromJson(strJSONData, Persons.class);
// 将 Persons 对象中包含的信息转换为字符串
for (int i = 0; i < persons.getPersons_Detail().size(); i++) {
ps += persons.getPersons_Detail().get(i).getId() + ":";
ps += persons.getPersons_Detail().get(i).getName() + ":";
ps += "\n";
}
// 在 UI 中显示解析后的结果
mPersons.setText(ps);
}
// 发送 HTTP POST 请求,获取 JSON 数据
private void sendRequest() {
// 定义请求 URL(这里用了模拟器访问本机 localhost 的地址)
String url = "http://10.0.2.2:8686/get_data.json";
// 定义需要传递的 JSON 数据
String json = "{\"id\": \"001\"}";
// 创建 OkHttpClient 对象
OkHttpClient client = new OkHttpClient();
// 定义请求体和请求对象
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
RequestBody body = RequestBody.create(json, mediaType);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
// 异步发送网络请求,并在响应成功或失败时回调 ok3cb 函数,通知应用程序处理结果
client.newCall(request).enqueue(ok3cb);
}
}
不知道上面原因,Android自带的虚拟手机获取不了数据,但用mumu模拟器成功了