Sabre HotelSearch报ERR.NGHP-DISTRIBUTION.INTERNAL_ERROR原因咨询
Sabre HotelSearch REST API 跨环境调用报错修复方案
问题现象
- Sabre Dev Studio官网Chrome浏览器在线调试环境调用
/v2.0.0/hotel/search接口,响应速度偏慢但可正常返回结果 - 携带完全一致的请求参数,在Sabre官方Rest2SG示例应用、Postman工具中发起请求,两个环境均返回400状态报错
- 报错返回内容如下:
{ "errorCode":"ERR.NGHP-DISTRIBUTION.INTERNAL_ERROR", "message":"Error occurred while invoking service restish:convertToOutputFormat:1.71.3", "status":"Incomplete", "type":"Application", "timeStamp":"2022-06-20T21:00:51-05" }
关联实现代码
Rest2SG示例应用中新增的getHotelSearch方法实现:
private void getHotelSearch() { Job job = new Job("Getting HotelSearch") { @Override protected IStatus run(IProgressMonitor monitor) { setText("Waiting for response..."); toggleAllButtons(false); try { Rest2SgRequest request = lockId > 0 ? new Rest2SgRequest(lockId) : new Rest2SgRequest(); // for the list of available service action names // please refer to REST documentation // this same as action in redapp.xml authorization request.setUrl("/v2.0.0/hotel/search"); //request.setHeaders(getContentDescription()) // previously generated document, normally developer will // have to prepare one by himself String payload = getRequestBody("sample.json"); // we // preload request.setPayload(payload); request.setHttpMethod(HTTPMethod.POST); request.setContentType("application/json"); request.setAuthTokenType(AuthTokenType.SESSIONLESS); Rest2SgServiceClient client = new Rest2SgServiceClient(COM); ClientResponse <Rest2SgResponse> rsp = client.send(request); LOGGER.info("Rest2Sg request processing success: " + rsp.isSuccess()); if (rsp.isSuccess()) { // check if processing ended in with success Rest2SgResponse response = rsp.getPayload(); String responseBody = response.getResponseBody(); response.getResponseCode(); response.getResponseHeaders(); setText(responseBody); } else { printErrors(rsp.getErrors()); System.out.println(rsp.getErrors().toString()); } } catch (Exception e) { e.printStackTrace(); } toggleAllButtons(true); return Status.OK_STATUS; } }; job.schedule(); }
使用的请求JSON参数:
{ "HotelSearchRQ": { "POS": { "Source": { "PseudoCityCode": "43X5" } }, "SearchCriteria": { "MaxResults": 20, "SortBy": "DistanceFrom", "SortOrder": "ASC", "TierLabels": false, "GeoSearch": { "GeoRef": { "Radius": 2, "UOM": "MI", "RefPoint": { "Value": "DFW", "ValueContext": "CODE", "RefPointType": "6", "StateProv": "TX", "CountryCode": "US" } } } } } }
报错根因
报错指向服务端convertToOutputFormat(输出格式转换)环节执行失败,核心原因是自定义调用环境与官方在线调试环境的默认请求配置存在差异:
- 官方在线调试环境会自动补全接口要求的
Accept: application/json请求头,明确告知服务端返回JSON格式结果;Postman、Rest2SG示例默认不会自动注入该头,服务端无法识别客户端期望的返回格式,触发格式转换层内部错误。 - Rest2SG示例代码中注释掉了
request.setHeaders(getContentDescription())配置行,缺失Sabre网关要求的渠道标识、会话上下文等基础请求头,导致请求被路由到存在已知bug的1.71版本格式转换组件,和在线调试环境的路由规则不一致。 - 在线调试环境默认使用公共测试权限集,自定义应用持有的凭证需要单独开通对应PCC下的Hotel Search接口访问权限,权限不匹配时也会触发该类通用内部报错。
修复方案
Postman环境调整
- 新增请求头
Accept: application/json - 确认请求认证头格式正确:Sessionless模式下使用
Authorization: Bearer <有效Token值> - 确认请求体编码为UTF-8无BOM格式,无多余不可见字符
Rest2SG示例应用调整
- 放开被注释的请求头配置,恢复
request.setHeaders(getContentDescription())代码调用,自动注入网关要求的基础头信息 - 显式添加返回格式声明,在
request.setContentType("application/json")代码后新增一行:request.addHeader("Accept", "application/json"); - 核对
redapp.xml配置,确认已添加/v2.0.0/hotel/search对应的接口动作授权,避免权限拦截导致的路由异常 - 升级Rest2SG依赖包到最新稳定版本,1.71.x系列版本存在格式转换逻辑的已知缺陷,升级后可直接规避该层报错
通用校验规则
- v2版本Hotel Search接口通过
Accept头协商返回格式,不要在请求路径后额外拼接.json/.xml后缀 - 确认当前使用的应用凭证,已关联请求中传入的PCC(伪城市码
43X5),且开通了Hotel Search接口的访问权限
内容的提问来源于stack exchange,提问作者Solv_it_kas
相关产品推荐
相关产品推荐

