1、新建OKHttpUtil工具类:
public class OKHttpUtil implements Callback {
public static final OKHttpUtil okutil = new OKHttpUtil();//单例模式,只允许当前工具类有一个实例
public static final OkHttpClient client = new OkHttpClient();//创建OkHttp的客户管理对象,也只有一个实例
private static Activity activity = null;
private MyCallBack mycallback=null;
private OKHttpUtil() {
}
/**
* ①数据初始化
*
* @param activity 传进来的acvitity赋值给当前类的acvitity
* @return 返回当前类的对象,方便连续调用该类中的方法进行连续传参(username,password)
*/
public static OKHttpUtil init(Activity activity) {
okutil.activity = activity;
return okutil;
}
/**
* ②
* get请求的封装方法
* 此处需要传参数url以及登录的username和password等参数,
* 所以需要③创建解析username和password的类GetParmars
*/
public void get(String url,GetParmars parmars,MyCallBack call) {
//⑨此时可以为get请求传参数
this.mycallback=call;//给自身实现的接口附一个实例
url=parseParmars(url,parmars);//获得包含所有参数的完整的url
//构造Request对象通过Request.Builder设置更多的参数
Request request=new Request.Builder().url(url).build();
client.newCall(request).enqueue(this);//异步请求
}
/**
* ②
* ⑪
* post请求的封装方法(get完成后再写)
*/
public void post(String url, RequestBody body, MyCallBack call){
this.mycallback=call;
Request request=new Request.Builder()
.url(url)
.post(body)
.build();
client.newCall(request).enqueue(this);
}
/**
* ⑥
* 获取完整的url,用于get请求明文传参
* @param url 不包含参数的url
* @param parmars 要解析添加到url中的参数对象
* @return 返回完整的url
* get请求中处理完了url还有一个callback接口可以封装,
* ⑦自定义callback接口类,定义 public void onFailure(Call call, IOException e)
* 和 public void onResponse(Call call, Response response)两个方法
*/
public String parseParmars(String url,GetParmars parmars){
Map<String,Object> map=parmars.map;//给map和GetParmars同一个实例
String data="";
if(map!=null){
Set<String> set=map.keySet();//遍历map中所有的键
for (String key:set) {
String value=map.get(key).toString();
data=data+key+"="+value+"&";//最后会多出一个&
}
if(!TextUtils.isEmpty(data)){
data=data.substring(0,data.length()-1);//去掉左后一个&
url=url+"?"+data;
}
}
return url;
}
/**
* ⑧
* 该工具类实现callback接口,重写里边的两个方法
* @param call
* @param e
*/
@Override
public void onFailure(final Call call, final IOException e) {
activity.runOnUiThread(new Runnable() {
//⑩填充方法中内容,
// 只有acvitity中才能执行runOnUIThread(Ui主线程)
@Override
public void run() {
if(mycallback!=null){
mycallback.onFailure(call,e);
}
}
});
}
@Override
public void onResponse(final Call call, final Response response) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(mycallback!=null){
mycallback.onResponse(call,response);
}
}
});
}
2、创建解析username和password的实体类 GetParmars:
/**
* ③创建解析username和password的实体类
* Created by Administrator on 2017/3/17.
*/
public class GetParmars {
public Map<String,Object> map=null;
/**
* ④
* 构造函数中进行实例化Map集合用于存放username和password的值
*/
public GetParmars() {
map=new HashMap<>();
}
/**
* ⑤
* @param key 集合中的键,也就是参数名
* @param obj 集合中的值
* @return 返回自身类的对象GetParmars,
* 方便连续调用add方法给多个参数复制(此处要给两个参数赋值:username和password)
*/
public GetParmars add(String key,Object obj){
map.put(key,obj);
return this;
}
3、自定义回调接口,定义和get与post请求中callback接口重名方法:
/**
* ⑦自定义回调接口类MyCallBack,定义和get与post请求中callback接口重名方法
* 然后让get与post请求所在的工具类OKHttp实现此自定义接口,重写此处方法,完成封装
* Created by Administrator on 2017/3/17.
*/
public interface MyCallBack {
void onFailure(Call call, IOException e);
void onResponse(Call call, Response response);
}
4、MainActivity implements MyCallBack实现自定义接口:
public class MainActivity extends AppCompatActivity implements MyCallBack{
private EditText et_username,et_password;
private Button btn_login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_username= (EditText) findViewById(R.id.et_username);
et_password= (EditText) findViewById(R.id.et_password);
btn_login= (Button) findViewById(R.id.btn_login);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// login();
loginByPost();
}
});
}
/**
*
* 默认get请求,不需要请求体
*/
private void login(){
// OkHttpClient okHttpClient=new OkHttpClient();
// //构建请求
// String username = et_username.getText().toString();
// String password = et_password.getText().toString();
// Request request=new Request.Builder().url("http://192.168.15.114:8080/HttpTest/Login?username="
// + username + "&password=" + password).build();
// okHttpClient.newCall(request).enqueue(new Callback() {//异步请求
// @Override
// public void onFailure(Call call, IOException e) {
//
// }
//
// @Override
// public void onResponse(Call call, Response response) throws IOException {
// final String res=response.body().string();
// //子线程可以操作主线程的方法
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
// Toast.makeText(getApplicationContext(),res,Toast.LENGTH_SHORT).show();
// }
// });
// }
// });
//
/**
* ⑩
* 此处需要MainAcvitity实现Mycallback接口
*/
GetParmars parmars=new GetParmars()
.add("username","zdsoft")
.add("password","123456");
OKHttpUtil.init(this).get("http://192.168.15.114:8080/HttpTest/Login",parmars,this);
}
/**
* ⑫
* 自定义post请求
* 需要增加RequestBody来存储请求的参数信息;
* 在Request.Builder中增加post(RequestBody)调用。 *
*/
private void loginByPost(){
// OkHttpClient client=new OkHttpClient();
//需要请求体
String username = et_username.getText().toString();
String password = et_password.getText().toString();
RequestBody requestBody=new FormBody.Builder().add("username",username).add("password",password).build();
OKHttpUtil.init(this).post("http://192.168.15.114:8080/HttpTest/Login",requestBody,this);
// Request request=new Request.Builder().url("http://192.168.15.114:8080/HttpTest/Login")
// .post(requestBody).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 {
// final String res=response.body().string();
// //发起子线程打印登录结果至主线程
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
// Toast.makeText(getApplicationContext(),res,Toast.LENGTH_SHORT).show();
// }
// });
// }
// });
}
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(this, "网络连接失败", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) {
try {
Toast.makeText(this, response.body().string(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}