一、SpringBoot接口分类
springboot后端接口分为3种,@RequestBody类型,@RequestParam类型以及@RequestParam("file") MultipartFile file类型,下面对这三种类型分别说明。
1.@RequestBody类型

在postman中使用body发送JSON语句

对于该种类型的接口,代码如下
String json = "{\n" +
//发送的json格式语句直接复制过来
"}";
OkHttpClient client = new OkHttpClient();//创建Http客户端
Request request = new Request.Builder()
.url("http://***.***.**.***:xxxx/ / ")//***.***.**.***为本机IP,xxxx为端口,/ / 为访问的接口后缀
.post(RequestBody.create(MediaType.parse("application/json"),json))
.build();//创建Http请求
Response response = client.newCall(request).execute();//执行发送的指令
final String responseData = response.body().string();//获取返回的结果
若返回的结果为json格式,可用JSONObject或JSONArray进行转换,以JSONArray为例
JSONArray jsonArray = new JSONArray(responseData);
for(int i = 0; i < jsonArray.length(); i++){//遍历
JSONObject jsonObject = jsonArray.getJSONObject(i);
String result = jsonObject.getString("xxx");//xxx为JSON语句中的key值,get到的为value值
}
2.@RequestParam类型

在postman中改变value的同时会改变url

对于该种类型的接口,代码如下(注解请参考1.类型中注解)
FormBody.Builder params = new FormBody.Builder();
params.add("xx",**);
params.add("xx",**);//xx为key,**为value
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://***.***.**.**:xxxx/ / ")
.post(params.build())
.build();
Response response = client.newCall(request).execute();
final String responseData = response.body().string();
若返回的结果为json格式,同上
3.@RequestParam("file") MultipartFile file
用于上传文件、图片等,目前还未用到,会补全。
二、对OkHttp的使用
在以上代码的运行过程中遇到一些网络访问的问题,下面一一讲解
首先,使用OkHttp之前需导入包。在Build.gradle(app)中添加

在AndroidManifest.xml中添加网络访问权限
![]()
运行发现第一个报错:CLEARTEXT communication to xxxx not permitted by network security policy

查询资料发现
在Android P系统的设备上,如果应用使用的是非加密的明文流量的http网络请求,则会导致该应用无法进行网络请求,https则不会受影响,同样地,如果应用嵌套了webview,webview也只能使用https请求。
故有三种方法,我采用的第三种方法
1、APP改用https请求
2、targetSdkVersion 降到27以下
3、在 res 下新增一个 xml 目录,然后创建一个名为:network_security_config.xml 文件(名字自定) ,内容如下,大概意思就是允许开启http请求
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
然后在APP的AndroidManifest.xml文件下的application标签增加以下属性
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...
/>
运行发现第二个报错(阿巴阿巴现在调不出来了)
![]()
在AndroidManifest.xml中添加
![]()
然后卸载app,重新运行
附:如果出现fail to connect to报错,检查一下ip地址是否有问题
三、android studio的多任务执行
android studio中发送post请求需放在子线程中,因为请求可能失败,为了不影响主线程,故建立子线程。
假设我点击按钮然后发送post请求,那么代码如下
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
//请求代码
}
}).start();
}
如果在线程中需要改变UI,需要在子线程中调用函数,将改变UI的代码扔回给主线程执行,不然会报错
假设我需要在子线程中show一个Toast
Toast.makeText(UserLoginActivity.this,"登录成功",Toast.LENGTH_SHORT).show();

有三种方式可以把请求回调给主线程
1.Activity.runOnUiThread(Runnable)
新增toast就是用这个函数
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(UserLoginActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
}
});
2.View.post(Runnable)
改变UI部件则使用这个函数
假设我
TextView username = findViewById(R.id.username);
那么当我需要在线程中改变username的内容时,就把setText放到以下函数中
username.post(new Runnable() {
public void run() {
username.setText("用户名");
}
});
3.View.postDelayed(Runnable,long)
与2相同,Delay了long的时间延迟响应
四、对post请求的说明
建立post请求可能存在通信不成功的情况,故在android studio中需把请求放在try函数中,结合上文改变UI的说明,代码如下
try {
//post请求
}catch (Exception e){
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(UserLoginActivity.this,"网络错误",Toast.LENGTH_SHORT).show();
}
});
}
示例代码登录(方法1)
username = findViewById(R.id.username);
password = findViewById(R.id.password);
loginButton = findViewById(R.id.button);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
usernameLogin = username.getText().toString();
passwordLogin = password.getText().toString();
new Thread(new Runnable() {
@Override
public void run() {
try {
String json = "{\n" +
" \"storePhone\": \"" + usernameLogin + "\",\n" +
" \"storePwd\": \"" + passwordLogin + "\"\n" +
"}";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://192.168.43.178:23333/store/login")
.post(RequestBody.create(MediaType.parse("application/json"),json))
.build();
Response response = client.newCall(request).execute();
final String responseData = response.body().string();
if(responseData.equals("true")){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(ShopLoginActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
}
});
}
else if(responseData.equals("false")){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(ShopLoginActivity.this,"用户名或密码错误",Toast.LENGTH_SHORT).show();
}
});
}
}catch (Exception e){
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(ShopLoginActivity.this,"网络错误",Toast.LENGTH_SHORT).show();
}
});
}
}
}).start();
}
});
运行结果

