在介绍OkHttp的Post请求的基本使用之前,我们需要了解什么是Post,以及什么是Get?对于android程序员来说,对这2个概念不像web工程师那样熟悉,在这里我们先简要说明Post和Get请求的区别:
Post或者Get只是Http协议中向后台服务器发送数据的一种机制,是Http协议的一个组成部分。
Post请求是将要提交到后台服务器的数据放在Http包的包体中。
Get请求是将数据放在URL之后,比如http://androidxx.cn/forum.php?mo ... d=11&extra=page%3D1,可以看到此URL由2部分组成,分别是http://androidxx.cn/forum.php和?后面的参数。这就是典型的Get请求方式。
因为Get请求时直接将参数放在URL后面,而URL的长度是有一定的限制,所以当传递的数据特别大的时候,Get请求就不能完成。
相比较,Post请求的参数是放在Http包的内部,不能轻易被看到;Get请求的参数直接是跟在URL之后,可以很容易被用户获取。所以,相对而言,Post的请求方式更安全。
在实际项目开发过程中,什么时候使用Get、什么时候使用Post呢?
Post(当涉及到参数的安全问题或者参数比较大的时候,应该使用Post请求方式),比如:
登陆
注册
上传
支付
下单
...
Get(Get就是获取的意思,项目开发中,如果是相对简单的查询类接口可以使用Get请求方式),比如:
获取图片
获取文章详情
...
以上就是Get和Post的一个简单的介绍,对刚入门的android程序员应该会有点帮助。然后,接下来我们开始OkHttp的Post异步请求方式的学习。
布局文件就不贴代码了,写两个EditText分别为用户名和密码的输入,id定位username和password,写一个button为提交按钮,id为submit。
public class MainActivity extends AppCompatActivity {
private String jsondata;
private String usernames,passwords;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText username = findViewById(R.id.username);
final EditText password = findViewById(R.id.password);
Button submit = findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (TextUtils.isEmpty(username.getText())) {
Toast.makeText(MainActivity.this,"请输入用户名",Toast.LENGTH_SHORT).show();
} else if (TextUtils.isEmpty(password.getText())) {
Toast.makeText(MainActivity.this,"请输入密码",Toast.LENGTH_SHORT).show();
} else {
usernames = username.getText().toString();
passwords = password.getText().toString();
okhttpData();
}
}
});
}
//post异步请求
private void okhttpData(){
Log.i("TAG","--ok-");
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client=new OkHttpClient();
//Form表单格式的参数传递
FormBody formBody = new FormBody
.Builder()
.add("username",usernames)//设置参数名称和参数值
.add("password",passwords)//设置参数名称和参数值
.build();
Request request = new Request
.Builder()
.post(formBody)//Post请求的参数传递
.url("http://ip:8080/login")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {
//此方法运行在子线程中,不能在此方法中进行UI操作。
jsondata = response.body().string();
//解析
jsonJXData(jsondata);
response.body().close();
}
});
}
}).start();
}
private void jsonJXData(String jsondata) {
if(jsondata!=null) {
try {
JSONObject jsonObject = new JSONObject(jsondata);
String data = jsonObject.getString("message");
if (data.equals("1")){
Looper.prepare();
Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MainActivity.this,HomeActivity.class);
startActivity(intent);
Looper.loop();
}else if (data.equals("2")){
Looper.prepare();
Toast.makeText(MainActivity.this,"用户名或密码不正确",Toast.LENGTH_SHORT).show();
Looper.loop();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Post同步请求只需要将同步请求中的方法enqueue换成execute方法。此处是针对表单格式数据的传递,如果是json数据格式:
//设置媒体类型。application/json表示传递的是一个json格式的对象
MediaType mediaType = MediaType.parse("application/json");
//使用JSONObject封装参数
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("参数名","参数值");
} catch (JSONException e) {
e.printStackTrace();
}
//创建RequestBody对象,将参数按照指定的MediaType封装
RequestBody requestBody = RequestBody.create(mediaType,jsonObject.toString());
Request request = new Request
.Builder()
.post(requestBody)//Post请求的参数传递
.url(Config.POST_URL)
.build();
try {
Response response = okHttpClient.newCall(request).execute();
String result = response.body().string();
Log.d("androixx.cn",result);
response.body().close();
} catch (IOException e) {
e.printStackTrace();
}
以上就是异步/同步post请求实现登录功能的方法