新聞中心
這篇文章給大家介紹怎么在Java中按時間梯度異步回調(diào)接口,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
我們提供的服務(wù)有:成都網(wǎng)站設(shè)計、做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、碭山ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的碭山網(wǎng)站制作公司
用到的技術(shù)如下:
?http請求庫,retrofit2
?隊列,LinkedBlockingQueue
?調(diào)度線程池,ScheduledExecutorService
3. 主要代碼說明
3.1 回調(diào)時間梯度的策略設(shè)計
采用枚舉來對策略規(guī)則進行處理,便于代碼上的維護,該枚舉設(shè)計三個參數(shù),級別、回調(diào)間隔、回調(diào)次數(shù);
/** * 回調(diào)策略 */ public enum CallbackType { //等級1,10s執(zhí)行3次 SECONDS_10(1, 10, 3), //等級2,30s執(zhí)行2次 SECONDS_30(2, 30, 2), //等級3,60s執(zhí)行2次 MINUTE_1(3, 60, 2), //等級4,5min執(zhí)行1次 MINUTE_5(4, 300, 1), //等級5,30min執(zhí)行1次 MINUTE_30(5, 30*60, 1), //等級6,1h執(zhí)行2次 HOUR_1(6, 60*60, 1), //等級7,3h執(zhí)行2次 HOUR_3(7, 60*60*3, 1), //等級8,6h執(zhí)行2次 HOUR_6(8, 60*60*6, 1); //級別 private int level; //回調(diào)間隔時間 秒 private int intervalTime; //回調(diào)次數(shù) private int count; }
3.2 數(shù)據(jù)傳輸對象設(shè)計
聲明抽象父類,便于其他對象調(diào)用傳輸繼承。
/** * 消息對象父類 */ public abstract class MessageInfo { //開始時間 private long startTime; //更新時間 private long updateTime; //是否回調(diào)成功 private boolean isSuccess=false; //回調(diào)次數(shù) private int count=0; //回調(diào)策略 private CallbackType callbackType; }
要傳輸?shù)膶ο螅^承消息父類;
/** * 工單回調(diào)信息 */ public class WorkOrderMessage extends MessageInfo { //車架號 private String vin; //工單號 private String workorderno; //工單狀態(tài) private Integer status; //工單原因 private String reason; //操作用戶 private Integer userid; }
3.3 調(diào)度線程池的使用
//聲明線程池,大小為16 private ScheduledExecutorService pool = Executors.newScheduledThreadPool(16); ...略 while (true){ //從隊列獲取數(shù)據(jù),交給定時器執(zhí)行 try { WorkOrderMessage message = MessageQueue.getMessageFromNext(); long excueTime = message.getUpdateTime()+message.getCallbackType().getIntervalTime()* 1000; long t = excueTime - System.currentTimeMillis(); if (t/1000 < 5) {//5s之內(nèi)將要執(zhí)行的數(shù)據(jù)提交給調(diào)度線程池 System.out.println("MessageHandleNext-滿足定時器執(zhí)行條件"+JSONObject.toJSONString(message)); pool.schedule(new Callable() { @Override public Boolean call() throws Exception { remoteCallback(message); return true; } }, t, TimeUnit.MILLISECONDS); }else { MessageQueue.putMessageToNext(message); } } catch (InterruptedException e) { System.out.println(e); } }
3.4 retrofit2的使用,方便好用。
具體可查看官網(wǎng)相關(guān)文檔進行了解,用起來還是比較方便的。http://square.github.io/retrofit/
retrofit初始化:
import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitHelper { private static final String HTTP_URL = "http://baidu.com/"; private static Retrofit retrofit; public static Retrofit instance(){ if (retrofit == null){ retrofit = new Retrofit.Builder() .baseUrl(HTTP_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; } }
如果需要修改超時時間,連接時間等可以這樣初始話,Retrofit采用OkHttpClient
import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import java.util.concurrent.TimeUnit; public class RetrofitHelper { private static final String HTTP_URL = "http://baidu.com/"; private static Retrofit retrofit; public static Retrofit instance(){ if (retrofit == null){ retrofit = new Retrofit.Builder() .baseUrl(HTTP_URL) .client(new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS)//連接時間 .readTimeout(30, TimeUnit.SECONDS)//讀時間 .writeTimeout(30, TimeUnit.SECONDS)//寫時間 .build()) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; } }
Retrofit使用通過接口調(diào)用,要先聲明一個接口;
import com.alibaba.fastjson.JSONObject; import com.woasis.callbackdemo.bean.WorkOrderMessage; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.POST; public interface WorkOrderMessageInterface { @POST("/api") CallupdateBatteryInfo(@Body WorkOrderMessage message); }
接口和實例對象準(zhǔn)備好了,接下來就是調(diào)用;
private void remoteCallback(WorkOrderMessage message){ //實例接口對象 WorkOrderMessageInterface workOrderMessageInterface = RetrofitHelper.instance().create(WorkOrderMessageInterface.class); //調(diào)用接口方法 CallobjectCall = workOrderMessageInterface.updateBatteryInfo(message); System.out.println("遠程調(diào)用執(zhí)行:"+new Date()); //異步調(diào)用執(zhí)行 objectCall.enqueue(new Callback () { @Override public void onResponse(Call call, Response response) { System.out.println("MessageHandleNext****調(diào)用成功"+Thread.currentThread().getId()); message.setSuccess(true); System.out.println("MessageHandleNext-回調(diào)成功"+JSONObject.toJSONString(message)); } @Override public void onFailure(Call call, Throwable throwable) { System.out.println("MessageHandleNext++++調(diào)用失敗"+Thread.currentThread().getId()); //失敗后再將數(shù)據(jù)放入隊列 try { //對回調(diào)策略初始化 long currentTime = System.currentTimeMillis(); message.setUpdateTime(currentTime); message.setSuccess(false); CallbackType callbackType = message.getCallbackType(); //獲取等級 int level = CallbackType.getLevel(callbackType); //獲取次數(shù) int count = CallbackType.getCount(callbackType); //如果等級已經(jīng)最高,則不再回調(diào) if (CallbackType.HOUR_6.getLevel() == callbackType.getLevel() && count == message.getCount()){ System.out.println("MessageHandleNext-等級最高,不再回調(diào), 線下處理:"+JSONObject.toJSONString(message)); }else { //看count是否最大,count次數(shù)最大則增加level if (message.getCount() 3.5結(jié)果實現(xiàn)
關(guān)于怎么在Java中按時間梯度異步回調(diào)接口就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
新聞標(biāo)題:怎么在Java中按時間梯度異步回調(diào)接口
轉(zhuǎn)載注明:http://www.ef60e0e.cn/article/gegejo.html