URLEncoder转码问题

URLEncoder转码问题2019独角兽企业重金招聘Python工程师标准>>>…

大家好,又见面了,我是你们的朋友全栈君。

场景描述:在与前端对接口,该请求需要调用别的渠道的业务,流程如下

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150578.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux离线安装docker_Unable to locate package vim

    linux离线安装docker_Unable to locate package vim首先报错Nomodulenamedpyyaml说明没有pyyaml在线安装windowslinux:pipinstallpyyaml亲测好用离线的情况下windowsPyYaml资源可以下载.whl文件然后pip安装即可离线的情况下linuxPyYaml资源可以下载.tar.gz文件然后pip安装即可pip可以直接安装.tar.gz文件#linux版样例[do…

    2022年10月9日
    0
  • linux下如何保存退出vim编辑器

    linux下如何保存退出vim编辑器命令:vimapp.py如果不存在app.py则会自动创建1.进入编辑器后按字母“i”即可进入编辑状态(此时左下角会出现 “插入”)2.退出的时候分为4种情况:保存退出、正常退出、不保存退出以及强制退出 2.1:保存退出:按“Esc”键后此时的“插入”会消失,然后按Shift+zz就可以保存修改内容并退出 2.2:不保存退出:当修改修改了一部分内容后发现修改错了,此时就会进行不保存退…

    2022年6月3日
    237
  • 华为拍月亮申请专利;魅族黄章回应李楠离职;GoLand 2019.2 Beta 发布 | 极客头条…

    华为拍月亮申请专利;魅族黄章回应李楠离职;GoLand 2019.2 Beta 发布 | 极客头条…快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持。「CSDN极客头条」,是从CSDN网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道。风里雨里,我们将每天为朋友们,播报最新鲜有料的新闻资讯,让所有技术人,时刻紧跟业界潮流。整理|胡巍巍责编|屠敏快讯速知 华为为拍月亮申请专利,详细介绍其中原理 连吃9张罚单仍不整改,上海…

    2022年5月22日
    35
  • Boltzmann/Softmax Exploration Strategy[通俗易懂]

    Boltzmann/Softmax Exploration Strategy[通俗易懂]Boltzmann/SoftmaxExplorationStrategy玻尔兹曼探索策略转自:Google图书《TheLogicofAdaptiveBehavior》

    2022年7月12日
    44
  • mysql主从误重复创建用户报错1396处理[通俗易懂]

    mysql主从误重复创建用户报错1396处理[通俗易懂]在mysql主从或者mysql分布式架构,某些时候主从中断报错1396,经分析发现重复创建用户导致。如何处理呢?

    2022年8月12日
    4
  • 12.推荐几款好用的搜索引擎「建议收藏」

    12.推荐几款好用的搜索引擎「建议收藏」1.多吉搜索https://www.dogedoge.com/多吉搜索是我接触的第一款无广告,无跟踪的搜索引擎,网上有它和谷歌搜索的对比,个人认为非常好用,但是最近好像用不了,总显示502badgateway,估计是被人攻击了。。。2.goobehttps://goobe.io/专为程序员设计的搜索引擎(搜索非技术相关的东西也很6),界面是这样事儿的而且可以通过快照访问stackoverflow和github,非常好用无广告,不跟踪3.萌搜http..

    2022年5月23日
    65

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号