大家好,又见面了,我是你们的朋友全栈君。
场景描述:在与前端对接口,该请求需要调用别的渠道的业务,流程如下
1、前端页面->Controller->调用健康险页面->Controller->前端页面
该请求通过get请求进行传参数,请求样例
https://test1-life.pingan.com/health/healthNotify?failBackUrl=https://test1-life.pingan.com/ilifecore/productMall/loading.html?productId=8000000241&channelCode=XCX00001&productCode=00001&actionType=underwrite&actionResult=2&successBackUrl=https://test1-life.pingan.com/ilifecore/productMall/loading.html?channelCode=XCX00001&productCode=00001&productId=8000000241&actionType=underwrite&actionResult=1&outChannelOrderId=30180000000001226447&productId=8000000241&platformSerialNo=20180820092030575
前端进行encodeURIComponent 进行编码:
https://test1-life.pingan.com/health/healthNotify?failBackUrl=https%3A%2F%2Ftest1-life.pingan.com%2Filifecore%2FproductMall%2Floading.html%3FproductId%3D8000000241%26channelCode%3DXCX00001%26productCode%3D00001%26actionType%3Dunderwrite%26actionResult%3D2&successBackUrl=https%3A%2F%2Ftest1-life.pingan.com%2Filifecore%2FproductMall%2Floading.html%3FchannelCode%3DXCX00001%26productCode%3D00001%26productId%3D8000000241%26actionType%3Dunderwrite%26actionResult%3D1&outChannelOrderId=30180000000001226447&productId=8000000241&platformSerialNo=20180820092030575
转码发送到后台,后台web服务器本身对其进行解码,Controller对参数进行处理
@RequestMapping("/health/healthNotify")
public void toHealthNotify(final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
log.info("HealthNotifyController---------toHealthNotify---------start");
String productId = LifeUtil.fixHttpRSAndTrim(request.getParameter("productId"));
String failBackUrl = LifeUtil.fixHttpRSAndTrim(request.getParameter("failBackUrl"));
String successBackUrl = LifeUtil.fixHttpRSAndTrim(request.getParameter("successBackUrl"));
String outChannelOrderId = LifeUtil.fixHttpRSAndTrim(request.getParameter("outChannelOrderId"));
String platformSerialNo = LifeUtil.fixHttpRSAndTrim(request.getParameter("platformSerialNo"));
log.info("HealthNotifyController---sent------"+failBackUrl);
log.info("转码后的"+URLEncoder.encode(failBackUrl,"UTF-8"));
//入参校验(platformSerialNo)
if (LifeUtil.isNull(platformSerialNo))
throw new OuterMessageException(ExReturnMeg.EUD0019);
//查询平台来源信息
ServiceRequest serviceRequest = new ServiceRequest();
serviceRequest.setParameter("thId", outChannelOrderId);
serviceRequest.setParameter("platformSerialNo", platformSerialNo);
serviceRequest.setRequestedServiceID("queryRelationInfoAction");
ServiceResponse serviceResponse = new ServiceResponse();
serviceResponse = ACDispatcher.dispatchService(serviceRequest, "pafaAC");
Map model = serviceResponse.getModel();
String productID = (String) model.get("productId");
// 校验(productId)
if(!productId.equals(productID))
throw new OuterMessageException(ExReturnMeg.EUD0020);
/** 注意:下面的这些参数请根据实际情况参考收银台接口文档替换 **/
Map<String, String> params = new TreeMap<String, String>();
params.put("outChannelOrderId", outChannelOrderId);
params.put("channelId", channelId);
params.put("productId", getHealthProductId(productId));
params.put("successBackUrl", URLEncoder.encode(request.getScheme()+"://"+request.getServerName()+"/health/backUrl?result=1&callBack="(URLEncoder.encode(successBackUrl,"UTF-8"), "UTF-8"));
params.put("failBackUrl", URLEncoder.encode(request.getScheme()+"://"+request.getServerName()+"/health/backUrl?result=0&callBack="+ URLEncoder.encode(failBackUrl,"UTF-8"),"UTF-8"));
params.put("signMethod", signMethod);
params.put("signature", encryptRequest(createLinkString(params), cyberarkV9Service.getPassword("ilife.health.signKey")));
log.info("HealthNotifyController----" + aitestURL + "?" + createLinkString(params));
//跳转至智能健告接口
response.sendRedirect(aitestURL + "?" + createLinkString(params));
}
关键的地方来了 ,但我们组装好参数,发送到健康险 ,健康险页面处理后,会通过health/backUrl 的Controller 把successBackUrl和failBackUrl返回回来,然后我们通过successBackUrl和failBackUrl 调用前端的接口 。
public void healthNotityCallBack(final HttpServletRequest request,
final HttpServletResponse response) throws Exception{
log
.info("HealthNotifyController---------callBack---------start");
String outChannelOrderId = LifeUtil.fixHttpRSAndTrim(request.getParameter("outChannelOrderId"));
String uwMedicalId = LifeUtil.fixHttpRSAndTrim(request.getParameter("uwMedicalId"));
String undwrtDecideType = LifeUtil.fixHttpRSAndTrim(request.getParameter("undwrtDecideType"));
String exclusiveAgreement = LifeUtil.fixHttpRSAndTrim(request.getParameter("exclusiveAgreement"));
String signature = LifeUtil.fixHttpRSAndTrim(request.getParameter("signature"));
String signMethod = LifeUtil.fixHttpRSAndTrim(request.getParameter("signMethod"));
String callBack = LifeUtil.fixHttpRSAndTrim(request.getParameter("callBack"));
log.info("HealthNotifyController---cb----"+callBack);
//根据thId获取保单信息
ServiceRequest serviceRequest1 = new ServiceRequest();
serviceRequest1.setParameter("thId", outChannelOrderId);
serviceRequest1.setRequestedServiceID("findAppPolicyByThIdAction");
ServiceResponse response1 = new ServiceResponse();
response1 = ACDispatcher.dispatchService(serviceRequest1, "pafaAC");
@SuppressWarnings("rawtypes")
Map model = response1.getModel();
AppPolicyDTO appPolicyDTO = (AppPolicyDTO) model.get("appPolicyDTO");
//保单
if(appPolicyDTO==null)
throw new OuterMessageException(ExReturnMeg.EUD0000);
appPolicyDTO.setResultID(uwMedicalId);
appPolicyDTO.setUdwDecide(undwrtDecideType);
//更新th表
ServiceRequest serviceRequest2 = new ServiceRequest();
serviceRequest2.setCurrentRequestObject(appPolicyDTO);
serviceRequest2.setRequestedServiceID("updateAppPolicyAction");
ServiceResponse response2 = new ServiceResponse();
response2 = ACDispatcher.dispatchService(serviceRequest2, "pafaAC");
Map<String, String> params = new TreeMap<String, String>();
params.put("outChannelOrderId", outChannelOrderId );
params.put("uwMedicalId", uwMedicalId );
params.put("undwrtDecideType", undwrtDecideType );
params.put("exclusiveAgreement", exclusiveAgreement );
params.put("signature", signature );
params.put("signMethod", signMethod );
log
.info("HealthNotifyController----" + callBack + "?" + createLinkString(params));
//跳转至小雨伞结果界面
if(callBack.contains("?")){
response.sendRedirect(callBack+"&"+createLinkString(params));
}else{
response.sendRedirect(callBack+"?"+createLinkString(params));
}
}
当我们 拿出回调的successBackUrl和failBackUrl的结果的时候,如下:
/wls/applogs/rtlog/ilife-core-stg1DMZ35021/ilife-core-stg1DMZ35021.out:2018-08-20 14:46:00.774 [INFO ] [HealthNotifyController] [215.128.194.20] {T=J0MLM5Kiv3x1ZSaB} HealthNotifyController---cb----https://test1-life.pingan.com/ilifecore/productMall/loading.html?channelCode=XCX00001
successBackUrl和failBackUrl 只是渠道的第一个参数,其他的参数都被kill掉了。
经过分析终于找到原因
在我们进行调用健康险的智能核保的过程中,健康险出了web服务器会进行一次解码的过程,本省的程序应该也会改url进行一次解码,这样就经过了两次解码
而我们也是进行两个编码
params.put("failBackUrl", URLEncoder.encode(request.getScheme()+"://"+request.getServerName()+"/health/backUrl?result=0&callBack="+URLEncoder.encode(failBackUrl,"UTF-8"),"UTF-8"));
经过两次编码后的报文是这样的
https%3a%2f%2ftest1-life.pingan.com%2fhealth%2fhealthNotify%3ffailBackUrl%253dhttps%253a%252f%252ftest1-life.pingan.com%252filifecore%252fproductMall%252floading.html%253fproductId%253d8000000241
%2526channelCode%253dXCX00001%2526productCode%253d00001%2526actionType%253dunderwrite%2526actionResult%253d2
而在智能核保系统经过两次解码的结果
https://test1-life.pingan.com/health/backUrl?failBackUrl=https://test1-life.pingan.com/ilifecore/productMall/loading.html?productId=8000000241&channelCode=XCX00001&productCode=00001&actionType=underwrite&actionResult=2
在按照如何的结果返回给我们系统的时候 ,我们在去 failBackUrl 的值的时候 https://test1-life.pingan.com/ilifecore/productMall/loading.html?productId=8000000241
导致返回给前端的内容一致不正确,还是对浏览器的机制不够熟练,希望小伙伴引以为戒
转载于:https://my.oschina.net/u/198077/blog/1931032
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150578.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...