Android Okhttp實現注冊登錄等功能,使用https


先記錄下大概流程

1、使用Okhttp發送post請求到服務端完成注冊登錄

2、添加https,實現https請求

3、遇到的問題:post請求多次發送造成后端數據不在同一session,解決:OkHttpClient創建時,傳入這個CookieJar的實現,就能完成對Cookie的自動管理

     下面是 RequestManager 類代碼:

package com.okhttpclient;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import static com.okhttpclient.MainActivity.handler;

/**
* Created by seceinfofs on 2016/11/28.
*/

public class RequestManager {

public static final String BASE_URL = "http://192.168.1.200/RayvanWebAuth.php";//根地址

public static final String REGISTER_URL = "register";//注冊地址
public static final String LOGIN_URL = "login";//登錄地址
public static final String LOGOUT_URL = "logout";//退出地址
public static final String AUTHCODE = "getAuthCode";//獲取驗證碼


private static volatile RequestManager mInstance;//單利引用
private OkHttpClient mOkHttpClient;//okHttpClient 實例
public Handler okHttpHandler;//全局處理子線程和M主線程通信
private Context context;


/**
* 初始化RequestManager
*/
public RequestManager(Context context) {


//初始化OkHttpClient
mOkHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)//設置超時時間
.readTimeout(10, TimeUnit.SECONDS)//設置讀取超時時間
.writeTimeout(10, TimeUnit.SECONDS)//設置寫入超時時間
.cookieJar(new CookieJar() {//OkHttpClient創建時,傳入這個CookieJar的實現,就能完成對Cookie的自動管理
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url, cookies);
}

@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.sslSocketFactory(getSSLSocketFactory(context, "cert.pem"))//添加https
.build();

//初始化Handler
okHttpHandler = new Handler(context.getMainLooper());
this.context = context;
}

/**
* 獲取單例引用
*/

public static RequestManager getInstance(Context context) {
RequestManager inst = mInstance;
if (inst == null) {
synchronized (RequestManager.class) {
inst = mInstance;
if (inst == null) {
inst = new RequestManager(context.getApplicationContext());
mInstance = inst;
}
}
}
return inst;
}



//實現https的類
private static SSLSocketFactory getSSLSocketFactory(Context context,String name) {

if (context == null) {
throw new NullPointerException("context == null");
}

//CertificateFactory用來證書生成
CertificateFactory certificateFactory;
InputStream inputStream = null;
Certificate certificate;

try {
inputStream = context.getResources().getAssets().open(name);
} catch (IOException e) {
e.printStackTrace();
}
try {

certificateFactory = CertificateFactory.getInstance("X.509");
certificate = certificateFactory.generateCertificate(inputStream);

//Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry(name,certificate);

//Create a TrustManager that trusts the CAs in our keyStore
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

//Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
return sslContext.getSocketFactory();

} catch (Exception e) {

}
return null;
}

/**
* 同步Post請求
* @param action
* @param name
* @param password
*/

public int requestPostBySyn(String action,String name,String password,String authCode) {
int rc = -1;
final String requestUrl = String.format("%s", BASE_URL);

RequestBody formBody = null;
if(action.equals(AUTHCODE)){
formBody = new FormBody.Builder()
.add("action",action)
.add("sendNumber", name)
.build();

} else if(action.equals(REGISTER_URL)){
formBody = new FormBody.Builder()
.add("action",action)
.add("username", name)
.add("password", password)
.add("authCode",authCode)
.build();
}else if(action.equals(LOGIN_URL)){
password = SHA256.Encrypt(password, "");
formBody = new FormBody.Builder()
.add("action",action)
.add("username", name)
.add("password", password)
.build();
}else if(action.equals(LOGOUT_URL)){
formBody = new FormBody.Builder()
.add("action",action)
.add("uuid", name)
.add("token", password)
.build();
}

final Request request = new Request.Builder()
.url(requestUrl).post(formBody).build();

Call call = mOkHttpClient.newCall(request);

try {
final Response response = call.execute();
final String result = response.body().string();

postToMianThread(result);
rc = 0;
} catch (IOException e) {
postToMianThread(null);
e.printStackTrace();
rc = -1;
}
return rc;
}

/**
* 異步Post請求
* @param action
* @param name
* @param password
*/

public void requestPostByAsyn(final String action, String name, String password, String authCode) {

final String requestUrl = String.format("%s", BASE_URL);
RequestBody formBody = null;
if(action.equals(AUTHCODE)){
formBody = new FormBody.Builder()
.add("action",action)
.add("sendNumber", name)
.build();

} else if(action.equals(REGISTER_URL)){
formBody = new FormBody.Builder()
.add("action",action)
.add("username", name)
.add("password", password)
.add("authCode",authCode)
.build();
}else if(action.equals(LOGIN_URL)){
password = SHA256.Encrypt(password, "");
formBody = new FormBody.Builder()
.add("action",action)
.add("username", name)
.add("password", password)
.build();
}else if(action.equals(LOGOUT_URL)){
formBody = new FormBody.Builder()
.add("action",action)
.add("uuid", name)
.add("token", password)
.build();
}

final Request request = new Request.Builder().url(requestUrl).post(formBody).build();

Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
postToMianThread(null);
}

@Override
public void onResponse(Call call, Response response) throws IOException {
final String res = response.body().string();
if(action.equals(LOGIN_URL)){
Message message =new Message();
Bundle bundle = new Bundle();
bundle.putString("key",res);
message.setData(bundle);
handler.sendMessage(message);
postToMianThread(res);
}
}
});
}

/**
* 請求響應
* @param result
*/
private void postToMianThread(final String result){
okHttpHandler.post(new Runnable() {
@Override
public void run() {
if(result!=null){
Toast.makeText(context, "..."+result, Toast.LENGTH_LONG).show();
}else {
Toast.makeText(context, "..."+"Fail", Toast.LENGTH_LONG).show();
}
}
});
}

}


參考文檔地址:
1、http://www.cnblogs.com/whoislcj/p/5526431.html
2、http://blog.csdn.net/lmj623565791/article/details/48129405
3、http://www.jianshu.com/p/1fdbcfcc962c
4、http://blog.csdn.net/dd864140130/article/details/52625666
5、http://www.open-open.com/lib/view/open1453422314105.html
6、http://www.cnblogs.com/LittleHann/p/3741907.html



Ps:這是第一次在網上寫東西,主要是為了記錄下來 以后忘了回頭看的時候方便 一會把demo上傳到網上


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM