昨晚睡一睡突然一個念頭閃過,
為什麼用那麼多try catch
昨天寫的程式中,我用了大量的try catch,原因其實也就是IDE提示要加,所以就加了
在程式中到底要在哪邊加try catch最適合,我也還在摸索
例外處理真的是一門大學問...
目前我在QpayHelper中全改成throws Exception的方式拋出,
因為沒意外的話都會是由Controller那邊呼叫,
我想在Controller再一起處理就可以了
另外,我建立了一個空的interface,
public interface QpayReq {
}
目的是要用來讓我的Data Object拿去 implements
順帶一提我發現可以用@JsonPropertyOrder(alphabetic=true)
來設定轉換json時是依照字母大小排序
因為發api的規則都是一致的,不同的只有發送的內容,
因此我把發api的request都寫成data object ,並implements QpayReq
接著在QpayHelper,
我打算用同一個方法來call永豐的那三個支付api,來降低程式的重複度
作法就是以QpayReq
、api名稱 當作參數,
這麼做可以讓我們把三支api的不同內容的data object可以用同個方法傳入,又不用擔心範圍開太大降低程式可讀性
public Map<String, Object> qpayHelper(QpayReq qReq,String apiName)throws IOException, GeneralSecurityException, DecoderException{
//1.nonce
String nonce=getNonce();
//2.hashID
String hashID=getHashID();
//3.iv
String iv = getIV(nonce);
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new QpayPropNamingStrategy());
mapper.setSerializationInclusion(Include.NON_NULL);
//4.message
String jsonContent =mapper.writeValueAsString(qReq);
String message = "";
message= encryptUtil.encrypt(jsonContent, hashID, iv);
//5.sign
Map<String, Object> map =
mapper.convertValue(qReq, new TypeReference<TreeMap<String, Object>>() {});
String sign = getSign(map,nonce,hashID);
//send to api
Map<String,String> request = new HashMap<String,String>();
request.put("Version", "1.0.0");
request.put("ShopNo",
SystemConfigUtil.systemConfMap.get("ShopNo"));
request.put("APIService", apiName);
request.put("Sign", sign);
request.put("Nonce", nonce);
request.put("Message", message);
String reqJson="";
reqJson = new ObjectMapper().writeValueAsString(request);
String res="";
res=util.post(
SystemConfigUtil.systemConfMap.get("Qpay_API_Url"), reqJson);
Map<String, String> resMap =new HashMap<String,String>();
resMap = mapper.readValue(res,
new TypeReference<HashMap<String, String>>() {});
String resSign =resMap.get("Sign");
String resNonce =resMap.get("Nonce");
String resMessage =resMap.get("Message");
String resiv= getIV(resNonce);
resMessage=encryptUtil.decrypt(resMessage, hashID, resiv);
Map<String, Object> resMessageMap =new TreeMap<String,Object>();
resMessageMap = mapper.readValue(resMessage,
new TypeReference<TreeMap<String, Object>>() {});
String signCheck = getSign(resMessageMap, resNonce, hashID);
if(signCheck.equals(resSign)){
System.out.println("Sign Check OK:"+signCheck);
}else{
throw new IllegalArgumentException("永豐回傳簽章驗證失敗");
}
return resMessageMap;
}
把try catch拿掉後 整體看起來也乾淨多了
回傳的值我打算直接回傳api回給我們的值轉成的map,
之後用Service 來call這個api方法後再各自對map做相對應的處理