Android studio进阶开发(六)--如何用真机通过okhttp连接服务器
我们学过了如何通过okhttp查询网络上已经发布的网页,但我们还需要在做全栈时保证前后端能够交互。
前要课程
okhttp的使用
真机端口连接
安全认证
由于http的安全性较差,在没有安全协议的情况下,使用自己的后端连接会报错,所以我们要在项目中配置安全文件:
r在 res/xml 目录下创建 network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /></trust-anchors></base-config>
</network-security-config>
在 AndroidManifest.xml 的 标签中启用配置:
android:networkSecurityConfig="@xml/network_security_config"
这样安全配置就完成了
后端
我们先看下后端的情况吧:
我们主要去调用name与type的属性,通过唯一的name去获取信息
代码
我们的代码基本上是在此文章中的代码进行改进的Android studio进阶开发(四)–okhttp的网络通信的使用
主要修改的地方:
private static final String BASE_URL = "http://192.168.43.9:8080/"; // 电脑的IP地址```java// 发起GET方式的HTTP请求private void doGet() {// 1. 构建带参数的URLHttpUrl url = new HttpUrl.Builder().scheme("http").host("192.168.43.9") // 替换为实际IP.port(8080).addPathSegments("threes/query/nametypes") // 层级路径的正确写法.addQueryParameter("name", "id") // 查询参数.build();OkHttpClient client = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS) // 添加超时配置.readTimeout(20, TimeUnit.SECONDS).build();Request request = new Request.Builder().url(url).header("Accept-Language", "zh-CN")// 移除不需要的Referer头.build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {runOnUiThread(() ->tv_result.setText("请求失败: " + e.getMessage()));}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {String resp = response.body().string();try {// 关键修改点:解析JSON数组JSONArray jsonArray = new JSONArray(resp);// 遍历数组中的对象StringBuilder result = new StringBuilder();for (int i = 0; i < jsonArray.length(); i++) {JSONObject item = jsonArray.getJSONObject(i);// 根据实际返回字段提取数据String name = item.optString("name", "未知");String type = item.optString("type", "未知");result.append("字段名称:").append(name).append("\n类型:").append(type).append("\n\n");}runOnUiThread(() ->tv_result.setText(result.toString()));} catch (JSONException e) {runOnUiThread(() ->tv_result.setText("数据解析失败\n原始数据:" + resp));}} else {runOnUiThread(() ->tv_result.setText("错误码:" + response.code()));}}});}
效果图:
这样,我们可以通过连接查询到我们后端数据库中的内容。
全部代码:
java:
package com.example.tttplean;import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import com.example.tttplean.Netconst;import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;import java.io.IOException;
import java.util.concurrent.TimeUnit;import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;public class Okhttp extends AppCompatActivity {private final static String TAG = "OkhttpCallActivity";private static final String BASE_URL = "http://192.168.43.9:8080/"; // 电脑的IP地址private static final String CITY_ENDPOINT = BASE_URL + "city";private final static String URL_LOGIN = Netconst.HTTP_PREFIX + "login";private LinearLayout ll_login; // 声明一个线性布局对象private EditText et_username; // 声明一个编辑框对象private EditText et_password; // 声明一个编辑框对象private TextView tv_result; // 声明一个文本视图对象private int mCheckedId = R.id.rb_get; // 当前选中的单选按钮资源编号@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_okhttp);ll_login = findViewById(R.id.ll_login);et_username = findViewById(R.id.et_username);et_password = findViewById(R.id.et_password);tv_result = findViewById(R.id.tv_result);RadioGroup rg_method = findViewById(R.id.rg_method);rg_method.setOnCheckedChangeListener((group, checkedId) -> {mCheckedId = checkedId;int visibility = mCheckedId == R.id.rb_get ? View.GONE : View.VISIBLE;ll_login.setVisibility(visibility);});findViewById(R.id.btn_send).setOnClickListener(v -> {if (mCheckedId == R.id.rb_get) {doGet(); // 发起GET方式的HTTP请求} else if (mCheckedId == R.id.rb_post_form) {postForm(); // 发起POST方式的HTTP请求(报文为表单格式)} else if (mCheckedId == R.id.rb_post_json) {postJson(); // 发起POST方式的HTTP请求(报文为JSON格式)}});}// 发起GET方式的HTTP请求private void doGet() {// 1. 构建带参数的URLHttpUrl url = new HttpUrl.Builder().scheme("http").host("192.168.43.9") // 替换为实际IP.port(8080).addPathSegments("threes/query/nametypes") // 层级路径的正确写法.addQueryParameter("name", "id") // 查询参数.build();OkHttpClient client = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS) // 添加超时配置.readTimeout(20, TimeUnit.SECONDS).build();Request request = new Request.Builder().url(url).header("Accept-Language", "zh-CN")// 移除不需要的Referer头.build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {runOnUiThread(() ->tv_result.setText("请求失败: " + e.getMessage()));}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {String resp = response.body().string();try {// 关键修改点:解析JSON数组JSONArray jsonArray = new JSONArray(resp);// 遍历数组中的对象StringBuilder result = new StringBuilder();for (int i = 0; i < jsonArray.length(); i++) {JSONObject item = jsonArray.getJSONObject(i);// 根据实际返回字段提取数据String name = item.optString("name", "未知");String type = item.optString("type", "未知");result.append("字段名称:").append(name).append("\n类型:").append(type).append("\n\n");}runOnUiThread(() ->tv_result.setText(result.toString()));} catch (JSONException e) {runOnUiThread(() ->tv_result.setText("数据解析失败\n原始数据:" + resp));}} else {runOnUiThread(() ->tv_result.setText("错误码:" + response.code()));}}});}// 发起POST方式的HTTP请求(报文为表单格式)private void postForm() {String username = et_username.getText().toString();String password = et_password.getText().toString();// 创建一个表单对象FormBody body = new FormBody.Builder().add("username", username).add("password", password).build();OkHttpClient client = new OkHttpClient(); // 创建一个okhttp客户端对象// 创建一个POST方式的请求结构Request request = new Request.Builder().post(body).url(URL_LOGIN).build();Call call = client.newCall(request); // 根据请求结构创建调用对象// 加入HTTP请求队列。异步调用,并设置接口应答的回调方法call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) { // 请求失败// 回到主线程操纵界面runOnUiThread(() -> tv_result.setText("调用登录接口报错:"+e.getMessage()));}@Overridepublic void onResponse(Call call, final Response response) throws IOException { // 请求成功String resp = response.body().string();// 回到主线程操纵界面runOnUiThread(() -> tv_result.setText("调用登录接口返回:\n"+resp));}});}// 发起POST方式的HTTP请求(报文为JSON格式)private void postJson() {String username = et_username.getText().toString();String password = et_password.getText().toString();String jsonString = "";try {JSONObject jsonObject = new JSONObject();jsonObject.put("username", username);jsonObject.put("password", password);jsonString = jsonObject.toString();} catch (Exception e) {e.printStackTrace();}// 创建一个POST方式的请求结构RequestBody body = RequestBody.create(jsonString, MediaType.parse("text/plain;charset=utf-8"));OkHttpClient client = new OkHttpClient(); // 创建一个okhttp客户端对象Request request = new Request.Builder().post(body).url(URL_LOGIN).build();Call call = client.newCall(request); // 根据请求结构创建调用对象// 加入HTTP请求队列。异步调用,并设置接口应答的回调方法call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) { // 请求失败// 回到主线程操纵界面runOnUiThread(() -> tv_result.setText("调用登录接口报错:"+e.getMessage()));}@Overridepublic void onResponse(Call call, final Response response) throws IOException { // 请求成功String resp = response.body().string();// 回到主线程操纵界面runOnUiThread(() -> tv_result.setText("调用登录接口返回:\n"+resp));}});}
}
相关文章:

Android studio进阶开发(六)--如何用真机通过okhttp连接服务器
我们学过了如何通过okhttp查询网络上已经发布的网页,但我们还需要在做全栈时保证前后端能够交互。 前要课程 okhttp的使用 真机端口连接 安全认证 由于http的安全性较差,在没有安全协议的情况下,使用自己的后端连接会报错,所以…...
如何解决网站服务器的异常问题?
当网站服务器出现异常情况,导致用户无法正常访问网页信息的时候,该如何解决这一问题呢?小编下面就带领大家共同探讨一下这一问题。 企业在面对网站服务器异常时,首先要对服务器硬件设备进行详细的检查,可以使用硬盘检测…...

WeakAuras Lua Script [ICC BOSS 11 - Sindragosa]
WeakAuras Lua Script [ICC BOSS 11 - Sindragosa] 冰冠堡垒Icecrown Citadel 冰龙 辛达苟萨(寒冰信标插件) 左 (绿,黄) 中(蓝,紫) 右(白,橙) lua script&…...
用户界面禁忌——基础原则
文章目录 基本原则1:关注用户及其任务,而不是技术基本原则2:首先考虑功能,然后才是表示基本原则3:与用户对任务的看法保持一致基本原则4:设计要符合常见情况基本原则5:不要分散用户对他们目标的…...

电脑开机后出现bootmgr is conmpressed原因及解决方法
最近有网友问我为什么我电脑开机后出现BOOTMGR is compressed,这个提示意思是:意思是启动管理器被压缩了,即使重启也无法正常进入系统。原因有很多,大部分是引导出现问题,或选错了启动硬盘所导致的,下面我们来详细分析…...

vite配置一个css插件
vite.config.js的plugins执行函数 该例子只是替换一些css,具体内容不重要,主要看形参的运用 // vite-plugin-css.js export default function cssPlugin() {return {name: vite-plugin-css-post, // 插件的名字,Vite 插件必须有名字enforce: post, // 设定插件执…...

React+Taro 微信小程序做一个页面,背景图需贴手机屏幕最上边覆盖展示
话不多说 直接上图 第一步 import { getSystemInfoSync } from tarojs/taro;第二步 render() {const cardBanner getImageUrlByGlobal(member-merge-bg.png);const { safeArea, statusBarHeight } getSystemInfoSync();const NAV_BAR_HEIGHT 44;const navBarHeight NAV…...

Spring框架学习day4--Spring集成Mybatis(IOC)
Spring集成Mybatis1.添加jar包(pom.xml)2.配置sqlSessionFactiory(spring.xml)3.再service类中注入Dao代理接口4.测试类5文件结构 Spring集成Mybatis Spring集成Mybatis其核心是将SqlSessionFactory交由Spring管理,并由 Spring管理…...
太阳系运行模拟程序-html动画
太阳系运行模拟程序-html动画 by AI: <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>交互式太阳系…...

【C++ Qt】容器类(GroupBox、TabWidget)内附思维导图 通俗易懂
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” ✍️绪论: 本章主要介绍了 Qt 中 QGroupBox 与 QTabWidget 控件。QGroupBox 是带标题的分组框,能容纳其他控件,有标题、对齐方式、是否…...

SOC-ESP32S3部分:18-串口
飞书文档https://x509p6c8to.feishu.cn/wiki/NqrMw6X8Si6sSqkyPbxcFRxGnid UART全称是通用异步接收器/发送器,ESP32-S3 芯片有 3 个 UART 控制器。每个 UART 控制器可以独立配置波特率、数据位长度、位顺序、停止位位数、奇偶校验位等参数。 串口文档参考…...
CSS 样式表的四种应用方式及css注释的应用小结
CSS样式表的四种应用方式及注释应用小结 一、样式表应用方式 内联样式(行内样式) <div style"color: #ff0000; font-size: 16px;">示例文本</div>特点:直接写在HTML标签的style属性中优先级:最高ÿ…...
五、web安全--XSS漏洞(2)--XSS相关payload
XSS 主要是针对网页客户端的一种攻击,那么就要执行 JavaScript 代码,那么无疑需要用到 JavaScript 语言以及在 HTML 中可以解析 JavaScript 代码的标签。 1、标签类 (1)script <script></script>标签是最直接的 xS…...
AI架构师的新工具箱:ChatGPT、Copilot、AutoML、模型服务平台
AI架构师不仅要懂架构、懂AI服务,还需要具备使用AI工具提升工作效率的能力。新一代AI工具已经成为架构师不可或缺的“工具箱”,帮助他们更高效地进行设计、部署、编码与优化。 以下介绍几类代表性工具,并说明它们在实际架构工作中的应用场景。 一、ChatGPT:生成架构设计文…...
关于智能体接入后端,在Apifox能够传参数给智能体的测试
from flask import Flask, request, jsonify, render_template import requests import json # 用于解析嵌套的 JSON 字符串app Flask(__name__)COZE_BOT_ID 7508736911423963162 COZE_API_KEY pat_cHXqrFzcvtktfmmlp4pjF3O2qmjioQW46uU8UNbUugyvSlFZclklpunc53DbR8ws COZE…...
有铜半孔工艺的制造难点与工艺优化
技术难点剖析 有铜半孔工艺在制造过程中面临多重挑战,主要集中在材料加工精度、孔壁完整性及良率控制三个方面: 铜层翘起与毛刺残留 半孔成型时,铣刀高速切割可能导致孔壁铜层被拉扯,产生翘起或残留铜屑,影响导电性能…...
python分步合并处理excel数据
文章目录 概要整体架构流程技术名词解释技术细节小结概要 客户需求 1. 背景与目标 用户需要将三个包含农业实验数据的Excel表格(AK、AN、AP)合并为一个结构化数据集,用于后续分析。每个表格包含相同类型的字段(如对照组与PSB处理组的样本数、均值、标准差),但需通过字…...
MC0309魔法项链
思路: 以数位贡献的思路来写这题, 统计每一位上为 1 的个数: 对于第 k 位,统计有多少个数在这一位上为 1,记作 cnts[k] 枚举每个数,逐位分析它对整体的贡献(即与其它数交互时的和)…...
为 Ubuntu 安装的软件创建桌面图标
如何为 Ubuntu 安装的软件创建桌面图标(.desktop 启动器) 在 Ubuntu 或其他 Linux 发行版中,我们常常通过压缩包(如 .tar.gz)或官方二进制方式安装软件。这种安装方式虽然灵活方便,但默认并不会将软件添加…...
uni-app 中开发问题汇总
uni-app 中 echarts 中的点击事件失效? 在 main.js 中 设置 window.wx{},这个方式,如果需要调 wx 中的方法会失效(如果默认后续不会调 wx 中的方法推荐使用) 降低版本,安装一个低版本的,比如&a…...

https下git拉取gitlab仓库源码
git init 创建仓库 参考下面创建公私秘钥对 注意不要以root用户身份创建公私钥,确保保存在/home/username GitLab配置ssh key - 阿豪聊干货 - 博客园 Your identification has been saved in /home/xxx/.ssh/id_ed25519 Your public key has been saved in /ho…...

距离计算范围查找距离排序
一 使用场景 目前基于某个位置查附近的人,附近的商家等等,查出来的结果添加距离,或者查附近多大范围内的人或者商家,然后按距离排序已经是IT界一个很通用的功能了。 二 距离计算搜索(百万点集以下) 2.1 球的定义 2.2 两点之…...

PS linux 基础篇1-AXI_DMA
系列文章目录 文章目录 系列文章目录前言一、AXI DMA ip核二、BD工程三、PS linux工程1.使用开源的xilinx_axidma-master工程验证驱动2.按照其他的开源进行就行,没什么写的了 前言 PL与PS之间快速的接口,本文为LOOP回环测试 一、AXI DMA ip核 MM2S mem…...

AI大模型学习三十、ubuntu安装comfyui,安装插件,修改返回405 bug,值得一看喔
一、说明 ComfyUI是一个开源的、基于节点的Web应用。它允许用户根据一系列文本提示(Prompt)生成图像。 ComfyUI使用扩散模型作为基础模型,并结合 ControlNet、Lora和LCM低阶自适应等模型,每个工具都由程序中的一个节点表示 二、开…...
11高可用与容错
一、Broker 高可用架构设计 1.1 RabbitMQ 镜像集群方案 集群搭建步骤 # 节点1初始化 rabbitmq-server -detached rabbitmq-plugins enable rabbitmq_management# 节点2加入集群 rabbitmqctl stop_app rabbitmqctl join_cluster rabbitnode1 rabbitmqctl start_app# 创建镜像…...
百度之星2024 初赛第一场 补给
百度之星2024 初赛第一场 补给 题干描述问题分析:C代码Java代码:Python代码补充说明: 题干描述 参考自马蹄集OJ,原文链接1 可怕的战争发生了,小度作为后勤保障工作人员,也要为了保卫国家而努力。 现在有 …...

Collection集合遍历的三种方法
1.foreach循环遍历 格式:for(元素的数据类型 变量名:数组或集合){ } 2.使用迭代器遍历 方法名称:Iterator<E> iterator() 说明:返回集合中的迭代器对象,该迭代…...

Taro on Harmony C-API 版本正式开源
Taro 是由京东发起并维护的开放式跨端跨框架解决方案,支持以 Web 的开发范式来实现小程序、H5、原生 APP 的跨端统一开发,从 18 年开源至今,在 GitHub 已累计获得 36,000 Stars。 Taro x 纯血鸿蒙 在过去的一年中,Taro 经历了显…...

知识隔离的视觉-语言-动作模型:训练更快、运行更快、泛化更好
25年5月来自PI的论文“Knowledge Insulating Vision-Language-Action Models: Train Fast, Run Fast, Generalize Better”。 视觉-语言-动作 (VLA) 模型通过将端到端学习与来自网络规模视觉-语言模型 (VLM) 训练的语义知识迁移相结合,为机器人等物理系统训练控制策…...

[ARM][架构] 02.AArch32 程序状态
目录 参考资料 1.程序状态 - PSTATE 2.用户模式的 PSTATE 信息 2.1.状态标志 2.2.溢出/饱和标志 2.3.大于等于标志 2.4.指令集状态 2.5.IT 块状态 2.6.端序控制 2.7.指令执行时间控制 3.用户模式访问 PSTATE - APSR 寄存器 4.系统模式的 PSTATE 信息 4.1.状态标志…...