ABAP循环调用BSP页面时http_client->response->get_cdata()无返回值问题
循环调用BSP页面获取HTML数据异常的解决方案
针对循环调用BSP页面时,首次请求正常返回HTML、后续请求状态码200但get_cdata()无返回的问题,以下是具体排查和解决步骤:
1. 重置HTTP客户端请求/响应上下文(关键)
即使将HTTP客户端实例创建移至循环外部,每次循环仍需重置请求和响应对象状态,避免上一次请求的残留数据干扰后续处理:
* 循环外创建客户端实例 CALL METHOD cl_http_client=>create_internal IMPORTING client = lr_http_client EXCEPTIONS plugin_not_active = 1 internal_error = 2 OTHERS = 3. IF sy-subrc <> 0. ev_error = abap_true. RETURN. ENDIF. LOOP AT it_data INTO DATA(ls_data). " 重置请求对象,清空所有头部和参数 lr_http_client->request->reset( ). " 重置响应对象,确保接收新的响应数据 lr_http_client->response->reset( ). " 生成BSP页面URL CALL METHOD cl_http_ext_webapp=>create_url_for_bsp_application EXPORTING bsp_application = iv_app bsp_start_page = iv_page bsp_start_parameters = lt_params IMPORTING abs_url = lv_url. cl_http_utility=>set_request_uri( request = lr_http_client->request uri = lv_url ). lr_http_client->request->set_header_field( name = '~request_method' value = 'GET' ). " 发送接收逻辑保持不变 lr_http_client->send( EXCEPTIONS ... ). IF sy-subrc = 0. lr_http_client->receive( EXCEPTIONS ... ). ENDIF. " 后续状态检查和数据读取逻辑... ENDLOOP. * 循环结束后关闭并释放客户端 lr_http_client->close( ). FREE lr_http_client.
2. 彻底释放客户端资源(循环内创建实例场景)
如果坚持在循环内创建客户端实例,需确保每次循环后彻底释放资源,避免内存泄漏或状态残留:
LOOP AT it_data INTO DATA(ls_data). " 生成URL等逻辑... CALL METHOD cl_http_client=>create_internal IMPORTING client = lr_http_client. IF sy-subrc <> 0. ... ENDIF. " 请求设置、发送接收逻辑... IF lv_rc = 200. ev_html = lr_http_client->response->get_cdata( ). ENDIF. " 关闭并释放实例 lr_http_client->close( ). FREE lr_http_client. " 强制释放,确保下次创建全新实例 ENDLOOP.
3. 绕过BSP页面缓存
BSP页面可能开启了缓存机制,导致后续请求返回空的缓存内容。可通过添加唯一参数强制页面重新生成内容:
* 在请求参数中添加时间戳,确保每次请求唯一 APPEND VALUE #( name = 'unique_id' value = |{ sy-datum }_{ sy-uzeit }| ) TO lt_params. CALL METHOD cl_http_ext_webapp=>create_url_for_bsp_application EXPORTING bsp_application = iv_app bsp_start_page = iv_page bsp_start_parameters = lt_params IMPORTING abs_url = lv_url.
也可直接在BSP页面属性中设置No Caching,禁用页面缓存。
4. 替代get_cdata(),直接读取原始响应数据
部分场景下get_cdata()无法正确解析响应编码,可读取原始二进制数据后转换为字符串:
IF lv_rc = 200. " 读取原始二进制响应数据 DATA(lv_raw_data) = lr_http_client->response->get_data( ). " 获取响应编码 DATA(lv_content_type) = lr_http_client->response->get_header_field( name = 'Content-Type' ). DATA(lv_encoding) = 'UTF-8'. " 默认编码 IF lv_content_type CS 'charset='. lv_encoding = lv_content_type+((lv_content_type CS 'charset=') + 8). TRANSLATE lv_encoding TO UPPER CASE. ENDIF. " 转换为字符串 ev_html = cl_abap_codepage=>convert_from( source = lv_raw_data codepage = lv_encoding ). ENDIF.
5. 强制BSP页面使用无会话模式
如果BSP页面依赖会话状态,循环调用中会话未重置可能导致逻辑异常。可在请求中添加头部强制无会话:
lr_http_client->request->set_header_field( name = '~session_mode' value = '0' " 0=无会话,1=有会话 ).
内容的提问来源于stack exchange,提问作者Mhsoftware
相关产品推荐
相关产品推荐

