日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Springboot集成聚合数据火车票API

發布時間:2024/1/8 javascript 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Springboot集成聚合数据火车票API 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Springboot集成聚合數據API

  • 聚合數據火車票代訂API
    • 關于聚合
    • 開始實現
    • 訂單狀態異步定時任務請求
    • Controller類來啦
    • 測試

聚合數據火車票代訂API

首先,吐吐槽。聚合數據提供的代訂功能會反饋很多很多狀態及對應狀態的信息,一不留神,你就會被一個未知的錯誤狀態碼搞得程序崩潰,就本篇文章也無法涵蓋它所有的狀態信息。

關于聚合

聚合唯一好點的是,它提供了一套完整的代訂火車票流程。從查詢車票信息,車站簡碼到提交訂單,取消未支付訂單,出票,最后退票整體流程已經完全覆蓋。不過它的退票有點惡心,需要人工聯系。所以我們就拋棄了它的退票功能。
具體官網請參見:https://www.juhe.cn/docs/api/id/173
具體官網說明文檔:http://code.juhe.cn/docs/201

開始實現

首先是整個的核心TicketUtil工具類,提供了提交,取消,狀態查詢和出票功能,并且檢測對應返回結果。由于訂單狀態不會實時返回,聚合數據這邊提供了一種方式設置回調,但想想,把系統的主動權交給聚合,所以本屌就拋棄了回調方式,而是使用主動請求方式去獲取訂單狀態。后面會提供對應的demo。首先咱們需要做好整個demo的根基,先看看對應的幾個工具類。

public static final String APPKEY = "XXXXXXXXXXX";//您所申請的appkey/*** 訂單狀態查詢* 接口url:http://op.juhe.cn/trainTickets/orderStatus*/public static ResponseResult getOrderStatus(String orderid){String url="http://op.juhe.cn/trainTickets/orderStatus?orderid="+orderid+"&key="+APPKEY;String data = HttpUtils.get(url);return checkRespnseData(data);}/*** 提交訂單,并返回聚合數據訂單編號* @param params* @return*/public static ResponseResult submitOrder(JSONObject params) {params.put("key", APPKEY);//預留訂單號params.put("user_orderid", getUserOrderId());String url = "http://op.juhe.cn/trainTickets/submit";String data = HttpUtils.sendPost(url, params);ResponseResult responseResult = checkRespnseData(data);return responseResult;}/*** 取消訂單* @param orderid* @return*/public static ResponseResult cancelOrder(String orderid){String url = "http://op.juhe.cn/trainTickets/cancel?dtype=json&orderid=" + orderid + "&key=" + APPKEY;String data = HttpUtils.get(url);ResponseResult responseResult = checkRespnseData(data);if(responseResult.getCode().equals(500) && responseResult.getData().equals("1")){responseResult.setCode(200);}return responseResult;}/*** 請求出票接口* @param orderid* @return*/public static ResponseResult outTicket(String orderid){String url="http://op.juhe.cn/trainTickets/pay?orderid="+orderid+"&key="+APPKEY;String data = HttpUtils.get(url);ResponseResult responseResult = checkRespnseData(data);return responseResult;}private static ResponseResult checkRespnseData(String data){if (StringUtil.isEmpty(data)){return ResponseResult.FAIL("接口請求異常");}JSONObject obj = JSONObject.parseObject(data);String errorCode = obj.getString("error_code");String reason = obj.getString("reason");//判斷是否調用成功 error_code = 0時調用成功if ("0".equals(errorCode)) {String result = obj.getString("result");if (StringUtil.isEmpty(result)) {return ResponseResult.FAIL("返回值為空");}JSONObject jsonResult = new JSONObject();//如果解析json異常,則證明處為出票階段,因為result中只包含一個String串try {jsonResult = JSONObject.parseObject(result);}catch (Exception e){return ResponseResult.SUCCESS(result);}String status = jsonResult.getString("status");//如果沒有status數據,則證明請求成功,返回的數據為對應的聚合orderidif(StringUtil.isEmpty(status)){return ResponseResult.SUCCESS(jsonResult);}//如果status等于1或者5,則訂單訂票不成功或者出票不成功,但如果是取消訂單操作則需要將狀態為1的情況轉換成successif( status.equals("1") || status.equals("5")){String message = jsonResult.getString("msg");return ResponseResult.FAIL(message,status);}return ResponseResult.SUCCESS(jsonResult);}else{return ResponseResult.FAIL(reason,errorCode);}}

返回結果類ResponseResult

public class ResponseResult {private static final Integer SUCCESS_CODE = 200;private static final Integer FAIL_CODE = 500;private static final Integer NO_LOGIN_CODE = 305;@ApiModelProperty(value = "類型編號,200:成功,500:不成功,305:未登錄")private Integer code;@ApiModelProperty(value = "返回消息內容")private String message;@ApiModelProperty(value = "返回數據")private Object data;public ResponseResult(Integer code, String message, Object data) {this.code = code;this.message = message;this.data = data;}public ResponseResult(Integer code, String message) {this.code = code;this.message = message;}public ResponseResult(Integer code) {this.code = code;}public ResponseResult(Integer code, Object data) {this.code = code;this.data = data;}public static ResponseResult SUCCESS(String message, Object data){return new ResponseResult(SUCCESS_CODE,message,data);}public static ResponseResult SUCCESS(Object data){return new ResponseResult(SUCCESS_CODE,data);}public static ResponseResult SUCCESS(){return new ResponseResult(SUCCESS_CODE);}public static ResponseResult SUCCESS(String message){return new ResponseResult(SUCCESS_CODE,message);}public static ResponseResult FAIL(){return new ResponseResult(FAIL_CODE);}public static ResponseResult FAIL(String message){return new ResponseResult(FAIL_CODE,message);}public static ResponseResult FAIL(Object data){return new ResponseResult(FAIL_CODE,data);}public static ResponseResult FAIL(String message,Object data){return new ResponseResult(FAIL_CODE,message,data);}public static ResponseResult NO_LOGIN(){return new ResponseResult(NO_LOGIN_CODE);}public static ResponseResult LOGIN_INVIDA(){return new ResponseResult(NO_LOGIN_CODE);}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}}

HttpUtils類

public static String sendPost(String url, JSONObject params) {String urlParams = "";for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {String name = (String) iter.next();String value = String.valueOf(params.get(name));if(StringUtil.isEmpty(urlParams)){urlParams = urlParams + name + "=" + value;}else{urlParams = urlParams + "&" + name + "=" + value;}//System.out.println(name +"-"+value);}PrintWriter out = null;BufferedReader in = null;String result = "";try {URL realUrl = new URL(url);// 打開和URL之間的連接URLConnection conn = realUrl.openConnection();// 設置通用的請求屬性conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 發送POST請求必須設置如下兩行conn.setDoOutput(true);conn.setDoInput(true);// 獲取URLConnection對象對應的輸出流out = new PrintWriter(conn.getOutputStream());// 發送請求參數out.print(urlParams);// flush輸出流的緩沖out.flush();// 定義BufferedReader輸入流來讀取URL的響應in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("發送 POST 請求出現異常!"+e);e.printStackTrace();}//使用finally塊來關閉輸出流、輸入流finally{try{if(out!=null){out.close();}if(in!=null){in.close();}}catch(IOException ex){ex.printStackTrace();}}return result;}public static String get(String url) {String result = "";BufferedReader br = null;InputStream inputstream = null;InputStreamReader isr = null;try {URL readerUrl = new URL(url);URLConnection conn = readerUrl.openConnection();conn.connect();inputstream = conn.getInputStream();isr = new InputStreamReader(inputstream);br = new BufferedReader(isr);result = br.readLine();} catch (Exception e) {System.out.println(e.getMessage());} finally {try {assert inputstream != null;inputstream.close();assert br != null;br.close();isr.close();} catch (IOException e) {e.printStackTrace();}}return result;}

訂單狀態異步定時任務請求

該類提供異步定時請求聚合數據訂單狀態查詢功能,當查詢到對應咱們所需要的狀態接口,執行自定義邏輯業務,發短信或者訂單入庫等等,想怎么做就看各位看官的心情了。
此類我角色很有很多線程安全問題,由于本屌不怎么擅長,所以優化神馬的就交給各位看官大大了。
另請自行定義對應的接口類哈

public class ScheduleServiceImp extends BaseService implements ScheduleService {@Value(value = "${cronQueryStatus}")private String cronQueryStatus;//自己寫cron表達式哈 本屌在springboot配置文件中添加了cronQueryStatus: 0/1 * * * * ?@Autowiredprivate ThreadPoolTaskScheduler threadPoolTaskScheduler;private ScheduledFuture<?> futureSubmit;private ScheduledFuture<?> futureOut;@Beanpublic ThreadPoolTaskScheduler threadPoolTaskScheduler() {return new ThreadPoolTaskScheduler();}public synchronized void startCronForSubmitOrder(String orderid) {futureSubmit = threadPoolTaskScheduler.schedule(new Runnable(){volatile int i = 0;@Overridepublic void run() {synchronized (this){System.out.println("開始查詢訂單狀態");//查詢訂單狀態3次返回異常結果,中斷查詢if(i >= 3){stopSubmitCron();}ResponseResult orderStatus = TicketsUtil.getOrderStatus(orderid);if(orderStatus.getCode().equals(500)){i++;System.out.println(i);log.error(orderStatus.getMessage());return;}JSONObject orderInfo = (JSONObject) orderStatus.getData();String status = orderInfo.getString("status");//如果訂單狀態是0:提交訂單,待處理,3:已支付,等待出票,則返回繼續查詢,該定時任務為了執行剛提交的訂單等待占座,因此各位看官及時把握if(status.equals("0") || status.equals("3")|| status.equals("4")|| status.equals("5")){return;}if(doYourSelfFunction()){ //此處添加自己業務方法stopSubmitCron();}}}}, new Trigger() {@Overridepublic Date nextExecutionTime(TriggerContext triggerContext) {return new CronTrigger(cronQueryStatus).nextExecutionTime(triggerContext);}});System.out.println("開始查詢提交訂單查詢定時任務");}public synchronized void startCronForOutOrder(String orderid) {futureOut = threadPoolTaskScheduler.schedule(new Runnable(){volatile int i = 0;@Overridepublic void run() {synchronized (this){System.out.println("開始查詢訂單出票狀態");//查詢訂單狀態3次返回異常結果,中斷查詢if(i >= 3){stopOutCron();}ResponseResult orderStatus = TicketsUtil.getOrderStatus(orderid);if(orderStatus.getCode().equals(500)){i++;System.out.println(i);log.error(orderStatus.getMessage());return;}JSONObject orderInfo = (JSONObject) orderStatus.getData();String status = orderInfo.getString("status");if(status.equals("0") || status.equals("3") || status.equals("1") || status.equals("2")){return;}if(modifyOrderStatus(orderInfo)){stopOutCron();}}}}, new Trigger() {@Overridepublic Date nextExecutionTime(TriggerContext triggerContext) {return new CronTrigger(cronQueryStatus).nextExecutionTime(triggerContext);}});System.out.println("開始出票訂單查詢定時任務");}public boolean cronSubmitStatus() {if (futureSubmit != null) {return futureSubmit.isCancelled();}return false;}public boolean cronOutStatus() {if (futureOut != null) {return futureOut.isCancelled();}return false;}public void stopSubmitCron() {if (futureSubmit != null) {futureSubmit.cancel(true);}System.out.println("取消提交訂單查詢定時任務");}public void stopOutCron() {if (futureOut != null) {futureOut.cancel(true);}System.out.println("取消出票訂單查詢定時任務");}

Controller類來啦

本屌只提供提交,取消和出票三接口demo哈

@PostMapping("/postIndent")public ResponseResult postIndent(@RequestBody JSONObject params){ResponseResult responseResult = TicketsUtil.submitOrder(params);if(responseResult.getCode().equals(500)){return responseResult;}JSONObject jsonResult = (JSONObject) responseResult.getData();String orderId = jsonResult.getString("orderid");Long startTime = System.currentTimeMillis();//觸發定時任務請求訂單狀態scheduleService.startCronForSubmitOrder(orderId);while(!scheduleService.cronSubmitStatus()) {continue;}Long endTime = System.currentTimeMillis();System.out.println((endTime - startTime)/1000);ResponseResult statusOrder = TicketsUtil.getOrderStatus(orderId);if(statusOrder.getCode().equals(500)){return statusOrder;}return returnResultByStatus(orderId);}//取消待支付的訂單@GetMapping("/cancel")public ResponseResult cancelOrder(String orderid){ResponseResult responseResult = TicketsUtil.cancelOrder(orderid);if(responseResult.getCode().equals(500)){return responseResult;}return responseResult;}//支付預留接口 請求出票@ApiOperation(value = "請求出票", notes = "請求出票")@GetMapping("/outTicket")public ResponseResult outTicket(String orderid){boolean payResult = pay();//自定支付方法//如果支付失敗,則return,成功執行出票方法,畢竟先收錢,后辦事嘛if (payResult){return responseResult;}ResponseResult responseResult = TicketsUtil.outTicket(orderid);if(responseResult.getCode().equals(500)){return responseResult;}//觸發定時任務請求訂單狀態scheduleService.startCronForOutOrder(orderid);return returnResultByStatus(orderid);}//自行處理返回提示,僅提供參照private ResponseResult returnResultByStatus(String orderid){String message = "1";switch (status){case "0" : message = "提交訂單成功,等待處理"; break;case "1" : message = "提交訂單成功,處理失敗"; break;case "2" : message = "訂單處理成功,等待支付"; break;case "3" : message = "訂單支付成功,等待出票"; break;case "4" : message = "訂單出票成功"; break;case "5" : message = "訂單出票失敗"; break;}return ResponseResult.SUCCESS(message,orderid);}

測試

提交訂單json demo,切記及時保存orderid,這個也是你后續的所有操作的唯一id。
另有一張是1元錢的車票 泰山到上高鎮的請各位自行封裝哈

{"start_time":"07:00","arrive_time":"08:30","arrive_days":"0","run_time_minute":"90","run_time":"1:30","dtype":"json","train_date":"2019-04-24","is_accept_standing":"yes","choose_seats":"1A","from_station_code":"XPY","to_station_code":"XAY","checi":"K680","passengers":"[{\"passengerid\":2,\"passengersename\":\"看官的姓名\",\"piaotype\":\"1\",\"piaotypename\":\"成人票\",\"passporttypeseid\":\"1\",\"passporttypeseidname\":\"二代身份證\",\"passportseno\":\"看官的身份證號\",\"price\":\"11.0\",\"zwcode\":\"1\",\"zwname\":\"硬座\"}]"}

執行完出票后結果返回出票成功,就需要各位看官撥打12306的客服電話人工查詢了,這個是真扯的地方。第一次發表文章,寫的不好,代碼也不咋滴,但還是希望能夠分享出來供各位看官參考參考。

總結

以上是生活随笔為你收集整理的Springboot集成聚合数据火车票API的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲性生活片 | 91久久国产综合久久91 | 少妇日皮视频 | 综合久久亚洲 | 亚洲成人黄色网 | www.com日本 | 日韩人妻无码精品综合区 | 国产乱淫av麻豆国产免费 | 久久9热| 男人的天堂2018 | 亚洲午夜av| 伊在线久久丫 | 伊人春色在线观看 | 久久www视频 | 国产丝袜自拍 | 99久久久无码国产精品免费麻豆 | 日韩av福利 | 日产精品久久久久 | 国产日产亚洲系列最新 | 中文字幕无码乱码人妻日韩精品 | 在线中文字幕播放 | 老司机av导航 | 日本免费成人 | 日本黄色免费看 | 青青色在线视频 | 中文字幕一区二区三区人妻不卡 | 亚洲欧美日韩国产一区二区 | 久久综合成人网 | 天堂8av| 丰满肉嫩西川结衣av | 日本一区二区视频在线观看 | 精品福利片| 亚洲午夜精品久久久 | 少妇脱了内裤让我添 | 日精品| 看个毛片 | 毛片网页| 欧美精品在线观看视频 | 亚洲AV无码成人国产精品色 | 国产美女无遮挡免费视频 | 尤果网福利视频在线观看 | 西方av在线| 日本r级电影在线观看 | 欧美第一视频 | 亚洲最新在线 | 国产精品日| 色欲久久久天天天综合网精品 | 大学生三级中国dvd 日韩欧美一区二区区 | 日不卡 | 中文字幕制服丝袜 | 国产精品一级二级 | 久久精品波多野结衣 | 久久免费高清视频 | 男人天堂tv | 99青草| 欧美黄一级 | 久久橹 | 欧美成人精品在线 | 亚洲国产日韩欧美一区二区三区 | ww久久 | 精品视频导航 | 欧美a性| 亚洲天堂男人的天堂 | 色综合中文字幕 | 久久爱综合网 | www.xxx.日本 | 免费av在线播放网址 | 精品美女一区二区 | 精品国产自在精品国产精小说 | 黄色99视频 | 69xxx国产 | 夜夜天堂 | 美妇湿透娇羞紧窄迎合 | 高清乱码免费网 | 成人免费在线视频 | 亚洲一区二区人妻 | 亚洲精品国产精品国自产网站按摩 | 亚洲αv | 蜜臀99久久精品久久久久小说 | 日美韩av| 欧美性免费 | 91久色| 精品国产一区二区三区久久久蜜臀 | 男人天堂2020| 看黄色一级大片 | 麻豆传媒一区 | 精品黑人一区二区三区国语馆 | 亚洲暴爽| www.亚洲综合 | 日本xx视频 | 日韩三级网 | av中文字幕一区 | 裸体裸乳被免费看视频 | 精品小视频 | 亚洲精品国产精品国自产 | 狠狠撸视频 | 亚洲va在线 | 国产真人做爰视频免费 | 中文字幕无码毛片免费看 |