javascript
Springboot集成聚合数据火车票API
Springboot集成聚合數(shù)據(jù)API
- 聚合數(shù)據(jù)火車票代訂API
- 關于聚合
- 開始實現(xiàn)
- 訂單狀態(tài)異步定時任務請求
- Controller類來啦
- 測試
聚合數(shù)據(jù)火車票代訂API
首先,吐吐槽。聚合數(shù)據(jù)提供的代訂功能會反饋很多很多狀態(tài)及對應狀態(tài)的信息,一不留神,你就會被一個未知的錯誤狀態(tài)碼搞得程序崩潰,就本篇文章也無法涵蓋它所有的狀態(tài)信息。
關于聚合
聚合唯一好點的是,它提供了一套完整的代訂火車票流程。從查詢車票信息,車站簡碼到提交訂單,取消未支付訂單,出票,最后退票整體流程已經完全覆蓋。不過它的退票有點惡心,需要人工聯(lián)系。所以我們就拋棄了它的退票功能。
具體官網請參見:https://www.juhe.cn/docs/api/id/173
具體官網說明文檔:http://code.juhe.cn/docs/201
開始實現(xiàn)
首先是整個的核心TicketUtil工具類,提供了提交,取消,狀態(tài)查詢和出票功能,并且檢測對應返回結果。由于訂單狀態(tài)不會實時返回,聚合數(shù)據(jù)這邊提供了一種方式設置回調,但想想,把系統(tǒng)的主動權交給聚合,所以本屌就拋棄了回調方式,而是使用主動請求方式去獲取訂單狀態(tài)。后面會提供對應的demo。首先咱們需要做好整個demo的根基,先看看對應的幾個工具類。
public static final String APPKEY = "XXXXXXXXXXX";//您所申請的appkey/*** 訂單狀態(tài)查詢* 接口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);}/*** 提交訂單,并返回聚合數(shù)據(jù)訂單編號* @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數(shù)據(jù),則證明請求成功,返回的數(shù)據(jù)為對應的聚合orderidif(StringUtil.isEmpty(status)){return ResponseResult.SUCCESS(jsonResult);}//如果status等于1或者5,則訂單訂票不成功或者出票不成功,但如果是取消訂單操作則需要將狀態(tài)為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 = "返回數(shù)據(jù)")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)");// 發(fā)送POST請求必須設置如下兩行conn.setDoOutput(true);conn.setDoInput(true);// 獲取URLConnection對象對應的輸出流out = new PrintWriter(conn.getOutputStream());// 發(fā)送請求參數(shù)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("發(fā)送 POST 請求出現(xiàn)異常!"+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;}訂單狀態(tài)異步定時任務請求
該類提供異步定時請求聚合數(shù)據(jù)訂單狀態(tài)查詢功能,當查詢到對應咱們所需要的狀態(tài)接口,執(zhí)行自定義邏輯業(yè)務,發(fā)短信或者訂單入庫等等,想怎么做就看各位看官的心情了。
此類我角色很有很多線程安全問題,由于本屌不怎么擅長,所以優(yōu)化神馬的就交給各位看官大大了。
另請自行定義對應的接口類哈
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();//觸發(fā)定時任務請求訂單狀態(tài)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,成功執(zhí)行出票方法,畢竟先收錢,后辦事嘛if (payResult){return responseResult;}ResponseResult responseResult = TicketsUtil.outTicket(orderid);if(responseResult.getCode().equals(500)){return responseResult;}//觸發(fā)定時任務請求訂單狀態(tài)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,這個也是你后續(xù)的所有操作的唯一id。
另有一張是1元錢的車票 泰山到上高鎮(zhèn)的請各位自行封裝哈
執(zhí)行完出票后結果返回出票成功,就需要各位看官撥打12306的客服電話人工查詢了,這個是真扯的地方。第一次發(fā)表文章,寫的不好,代碼也不咋滴,但還是希望能夠分享出來供各位看官參考參考。
總結
以上是生活随笔為你收集整理的Springboot集成聚合数据火车票API的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业战略环境分析
- 下一篇: 2021年金属非金属矿山支柱考试题库及金