token自动刷新 并处理并发问题

This commit is contained in:
lijia 2024-11-29 18:08:34 +08:00
parent f648050328
commit f0e7d63ae0
6 changed files with 188 additions and 11 deletions

View File

@ -12,7 +12,10 @@ import com.arpa.hndahesudintocctmsdriver.request.bean.newlj.ShipmentStatusBean;
import com.arpa.hndahesudintocctmsdriver.request.bean.newlj.UpimgBean;
import com.dahe.mylibrary.net.CommonResponseBean;
import java.util.HashMap;
import io.reactivex.rxjava3.core.Observable;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
@ -38,6 +41,9 @@ public interface Api {
@POST(BASE_URL+"openapi/enterprises/login")
Observable<CommonResponseBean> getToken(@Body LjTokenBean bean);
@POST(BASE_URL+"openapi/enterprises/login")
Call<HashMap<String, String>> getRefreshToken(@Body LjTokenBean bean);
/**
* 刷新token

View File

@ -0,0 +1,114 @@
package com.arpa.hndahesudintocctmsdriver.request.net
import okhttp3.Interceptor
import okhttp3.Request
import okio.IOException
import retrofit2.Response
import java.util.concurrent.atomic.AtomicBoolean
/**
* @ClassName ApiInterceptor
* @Author john
* @Date 2024/11/29 17:05
* @Description TODO
*/
class ApiInterceptor : Interceptor {
// 需要验证token的接口的路径集合
// private val checkTokenInterface = arrayListOf(
// "/example/user/info,
// "/example/user/info/edit"
// )
// 是否正在刷新token
// 使用AtomicBoolean确保多线程中获取的值一致
// private var refreshingToken = AtomicBoolean(false)
//
// private val authHeaderKey = "token-key"
//
// // 当前token
// private var currentToken = "tokenValue"
// override fun intercept(chain: Interceptor.Chain): Response {
// 根据接口路径判断是否需要验证token
// val checkToken = checkTokenInterface.contains(chain.request().url.encodedPath)
// // 需要验证token则添加请求头不需要则保持原样
// var request = if (checkToken) {
// chain.request().newBuilder()
// .addHeader(authHeaderKey, currentToken)
// .build()
// } else {
// chain.request()
// }
// // 获取响应
// var response = chain.proceed(request)
// if (checkToken) {
// // 需要验证token处理响应判断token是否过期
// response.body?.let { responseBody ->
// try {
// if (判断token过期的条件) {
// runBlocking {
// // 请求头中的token与currentToken仍然一样则需要刷新token
// // 确保多线程中不会重复刷新
// if (request.header(authHeaderKey) == currentToken){
// // 标记为正在刷新token
// if (refreshingToken.compareAndSet(false, true)) {
// refreshToken(chain).takeIf { it.isNotEmpty() && it.isNotBlank() }?.let { newToken ->
// // 保存newToken
// currentToken = newToken
// }
// // 标记为刷新token已结束
// refreshingToken.set(false)
// }
// }
// // async{}.await()会等待方法块内的代码执行完毕。
// // 等到refreshingToken为false时才会执行后续代码。
// if (async { stopRefreshingToken() }.await()) {
// // 携带newToken执行原请求获取响应
// response = chain.proceed(chain.request().newBuilder()
// .addHeader(authHeaderKey, currentToken)
// .build())
// }
// }
// }
// } catch (e: Exception) {
// e.printStackTrace()
// }
// }
// }
// // 返回最终的响应结果。
// // 刷新token也可能失败此时返回原响应可以让用户重新登录。
// return response
// }
//
// private fun refreshToken(chain: Interceptor.Chain): String {
// // 创建刷新token的请求
// val refreshTokenRequest = Request.Builder()
// .url("refresh token url")
// .addHeader(authHeaderKey, currentToken)
// .get()
// .build()
// return try {
// // 获取响应并解析获得新token
// val refreshTokenResponse = chain.proceed(refreshTokenRequest)
// refreshTokenResponse.token
// } catch (e: IOException) {
// // 失败时返回空字符串
// ""
// }
// }
//
// private suspend fun stopRefreshingToken(): Boolean {
// return if (refreshingToken.get()) {
// // 仍在刷新token中延迟1秒后再次执行此方法
// delay(1000)
// stopRefreshingToken()
// } else {
// true
// }
// }
override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
TODO("Not yet implemented")
}
}

View File

@ -1,19 +1,31 @@
package com.arpa.hndahesudintocctmsdriver.request.net;
import static com.dahe.mylibrary.utils.BaseSPUtils.NEW_LJ_TOKEN;
import android.text.TextUtils;
import android.util.Log;
import com.arpa.hndahesudintocctmsdriver.App;
import com.arpa.hndahesudintocctmsdriver.constant.NewLJConstant;
import com.arpa.hndahesudintocctmsdriver.request.bean.newlj.LjTokenBean;
import com.arpa.hndahesudintocctmsdriver.util.NewLJUtils;
import com.arpa.hndahesudintocctmsdriver.util.SPUtils;
import com.dahe.mylibrary.CommonBaseLibrary;
import com.dahe.mylibrary.net.CommonResponseBean;
import com.dahe.mylibrary.net.ResultException;
import org.json.JSONObject;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import io.reactivex.rxjava3.core.Observable;
import kotlin.jvm.Synchronized;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
@ -30,6 +42,9 @@ public class JsonInterceptor implements Interceptor {
public JsonInterceptor() {
}
// 使用AtomicBoolean确保多线程中获取的值一致
private AtomicBoolean refreshingToken = new AtomicBoolean(false);
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
@ -45,14 +60,24 @@ public class JsonInterceptor implements Interceptor {
Log.i(TAG, "result-body= " + responseBodyStr);
try {
// if (401==response.code()){
// NewLJUtils.getInstance().refreshToken(App.getApp());
// }
JSONObject jsonObject = new JSONObject(responseBodyStr);
String str = jsonObject.optString("data");
int code = jsonObject.optInt("code");
if (401 == code) {
refreshToken();
// if (execute.body() != null) {
// String refreshToken = execute.body().get("token");
// SPUtils.put(App.getApp(), NEW_LJ_TOKEN, refreshToken);
// }
response.close();
try {
return chain.proceed(request);
} catch (IOException e) {
e.printStackTrace();
}
}
if (-1 == code) {
jsonObject.put("data", new JSONObject());
throw new ResultException();
@ -70,4 +95,25 @@ public class JsonInterceptor implements Interceptor {
response = response.newBuilder().body(responseBody).build();
return response;
}
@Synchronized
private void refreshToken() throws IOException {
Api api = CommonBaseLibrary.getRetrofit().newBuilder()
.client(new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build())
// .addNetworkInterceptor(new TokenInterceptor())
.build().create(Api.class);
LjTokenBean ljTokenBean = new LjTokenBean();
ljTokenBean.setEnterpriseCode(NewLJConstant.ENTER_PRISE_CODE);
ljTokenBean.setEnterpriseIdentity(NewLJConstant.ENTER_PRISE_IDENTITY);
ljTokenBean.setEnterpriseKey(NewLJConstant.ENTER_PRISE_KEY);
retrofit2.Response<HashMap<String, String>> execute = api.getRefreshToken(ljTokenBean).execute();
if (execute.body() != null) {
String refreshToken = execute.body().get("token");
SPUtils.put(App.getApp(), NEW_LJ_TOKEN, refreshToken);
}
}
}

View File

@ -88,14 +88,14 @@ public abstract class RxHttpCallBack<T> {
}
if ("401".equals(t.getCode())) {
NewLJUtils.getInstance().refreshToken(mContext);
// NewLJUtils.getInstance().refreshToken(mContext);
// UiAuxiliary.delLogin(mContext);
// Intent intent = new Intent(mContext, MainActivity.class);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// mContext.startActivity(intent);
// ToastUtils.showToast(mContext,"您的账号再异地登录,请重新登录");
}else{
ToastUtils.showToast(mContext,t.getMsg());
// ToastUtils.showToast(mContext,t.getMessage());
}
// if (t.getMessage().getMsg_code() == 100 && SPUtils.hasUserInfo(mContext)) {

View File

@ -24,8 +24,10 @@ import com.arpa.hndahesudintocctmsdriver.event.HomeEvent;
import com.arpa.hndahesudintocctmsdriver.event.PersonEvent;
import com.arpa.hndahesudintocctmsdriver.ui.business.BusinessActivity;
import com.arpa.hndahesudintocctmsdriver.util.MessageUtils;
import com.arpa.hndahesudintocctmsdriver.util.NewLJUtils;
import com.arpa.hndahesudintocctmsdriver.util.PermissionUtils;
import com.bumptech.glide.Glide;
import com.dahe.mylibrary.callback.OnGDResultListener;
import com.dahe.mylibrary.utils.ActivityUtils;
import com.esign.esignsdk.EsignSdk;
import com.esign.esignsdk.data.AuthEvent;
@ -141,6 +143,17 @@ public class PersonalAuthActivity extends BaseAppCompatActivity {
super.onCreate(savedInstanceState);
StateStyleUtil.stateTextColor(this);
setContentView(R.layout.activity_wode_data);
NewLJUtils.getInstance().getInvoices(this, new OnGDResultListener() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(String var1, String var2) {
}
});
con = this;
act = this;
r1 = findViewById(R.id.r1);

View File

@ -77,7 +77,6 @@ public class NewLJUtils {
public void onSuccess(CommonResponseBean t) {
super.onSuccess(t);
SPUtils.put(ctx, NEW_LJ_TOKEN, t.getToken());
refreshToken(ctx);
}
}));
}
@ -113,7 +112,6 @@ public class NewLJUtils {
public void onSuccess(CommonResponseBean t) {
super.onSuccess(t);
SPUtils.put(ctx, NEW_LJ_TOKEN, t.getToken());
refreshToken(ctx);
if (listener != null)
listener.onSuccess();
}
@ -472,7 +470,7 @@ public class NewLJUtils {
@Override
public void onCodeError(Context mContext, CommonResponseBean<CommonResponseBean<InvoicesBean>> t) {
super.onCodeError(mContext, t);
Log.e("NewLJUtils", t.getMessage());
// Log.e("NewLJUtils", t.getMsg().toString());
}
}));
}