调用SAP新API出现"No error field found in JSON"(VDM:401)授权问题求助
解决SCP环境下调用SAP新OData API的权限与JSON解析错误问题
嘿,我来帮你拆解下这个问题——你遇到的其实是两个关联的问题:核心是SCP环境下调用新API的权限不足,而"No error field found in JSON"只是权限错误引发的间接报错(因为新API的错误响应格式和旧接口不一样,你的代码没适配)。咱们一步步来解决:
问题梳理
先明确下你的场景:
- 本地开发时,Java应用调用
API_BUSINESS_PARTNER完全正常,能返回数据给SAPUI5前端 - 部署到SCP后,调用该接口抛出**"No error field found in JSON",查看
ODataConnectivityUtil日志发现明确提示用户无权限** - 旧接口
MMIM_MATERIAL_DATA_SRV在SCP上能正常工作,但调用另一个新接口API_PRODUCT_SRV时触发同样错误,推测所有SAP新发布的OData API都有这个问题
问题根源分析
权限配置差异:SAP新的标准API(比如API Business Hub里的
API_BUSINESS_PARTNER、API_PRODUCT_SRV)和旧的自定义/传统OData接口的权限校验逻辑完全不同:- 新API需要更细粒度的权限对象,比如
S_SERVICE权限对象里必须包含对应新API的服务名称,还可能需要业务专属的权限对象(比如BUPA相关权限用于业务伙伴API) - 旧接口可能用的是宽松的权限配置,刚好覆盖了SCP上的调用用户
- 新API需要更细粒度的权限对象,比如
错误响应格式不兼容:当新API返回权限错误时,它的JSON响应结构和旧接口不一样,你的Java错误处理代码还是按照旧接口的格式去查找
error字段,导致解析失败,抛出"No error field found in JSON"。
分步解决方案
1. 先搞定核心的权限问题
这是根源,必须先解决:
- 登录SAP后台(比如S/4HANA系统),检查SCP调用所用账号的权限:
- 确保账号拥有
S_SERVICE权限对象,其中SERVICENAME要包含API_BUSINESS_PARTNER、API_PRODUCT_SRV这些新API的完整服务名,ACTVT设置为03(读取权限) - 补充新API对应的业务权限:比如
API_BUSINESS_PARTNER需要BUPA_DISP(业务伙伴显示)这类权限对象,具体可以查SAP API Business Hub里对应API的权限文档
- 确保账号拥有
- 如果是用SCP的Destination配置来调用API,要确认Destination里的认证信息(比如Basic Auth账号、SAML断言对应的用户)已经配置了上述权限
2. 修复JSON错误解析逻辑
调整Java代码里的错误处理,兼容新API的响应格式:
SAP新OData API的错误响应通常是这样的结构:
{ "error": { "code": "403", "message": { "lang": "en", "value": "Authorization check failed" }, "innererror": { "transactionid": "XXXXXXX", "error": { "code": "SICF_RUNTIME_ERROR", "message": "You are not authorized" } } } }
而旧接口的错误格式可能更简单,你的代码可能直接读取error.message这类字段,但新接口的message是嵌套对象。
建议用通用的JSON解析方式(比如Jackson的JsonNode)来处理,避免固定POJO的限制:
// 示例:处理HTTP响应的错误逻辑 if (httpResponse.getStatusLine().getStatusCode() >= 400) { String errorResponse = EntityUtils.toString(httpResponse.getEntity()); ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(errorResponse); // 先尝试解析新API的错误格式 JsonNode errorNode = rootNode.path("error"); if (!errorNode.isMissingNode()) { String errorMsg = errorNode.path("message").path("value").asText("Unknown authorization error"); log.error("New API Error: {}", errorMsg); throw new CustomBusinessException(errorMsg); } else { // 兼容旧接口的错误格式 String oldErrorMsg = rootNode.path("error").asText("Unknown error"); log.error("Old API Error: {}", oldErrorMsg); throw new CustomBusinessException(oldErrorMsg); } }
3. 验证测试
- 先用Postman或者SAP API Business Hub的测试工具,用SCP调用所用的账号测试新API,确认能正常返回数据
- 部署调整后的Java代码,再测试SAPUI5前端的调用流程,确认两个错误都消失
内容的提问来源于stack exchange,提问作者N.Kryl
相关产品推荐
相关产品推荐

