You are using HR ESS Personal Profile WebDynpro HRESS_A_PERSINFO and you can see picture being displayed in WebDynpro when accessing application within network. However, you cannot see picture when accessing application outside network.
In your system landscape a reverse proxy i.e. Web Dispatcher is used in the network. Web Dispatcher is reachable over internet and it redirects request over configured URL and Port to servers/services which are behind the firewall.
Picture which is displayed within Personal Profile Webdynpro are hosted using ContentServer service of SAP ERP server. Assuming everything else is configured right you can execute function module HRWPC_RFC_EP_READ_PHOTO_URI to see the URL of picture of an employee by passing their PERNR. URL being generated would look like below where myerpsys.com is internal URL or your content server.
http://myerpsys.com:1090//ContentServer/ContentServer.dll?get&pVersion=0047&contRep=AB&docId=005056A54E011ED78AD2175760508D…
To reach content server form outside network URL must contain name and port of the Web Dispatcher and not of your internal server name (myerpsys.com). There are a lots of topics on scn and also in sap notes on how to resolve this but none of them worked for me and I had to, in the end, put an enhancement in WebDynpro to generate URL and Port which is configured for Web Dispatcher and have it redirected to SAP ERP ContentServer service.
SAP Note 2465728 talk about adjusting entries in table HTTPURLLOC to generate Web Dispatcher URL and Port but no matter what is specified in this table makes no difference to URL generated. DB trace confirms that code does not look at table HTTPURLLOC while generating URL.
Resolution
The URL of content server images should point to the same as Web Dispatcher domain and protocol.Follow steps below to fix this scenario:
Configure the /sap/bc/contentserver service and user authentication:SAP Note 685521 – Logon data for /sap/bc/contentserver service
If Web Dispatcher is using HTTPS Protocol: Enable HTTPS in MIME Content Repository: SAP Note 712330 – Accessing server content with HTTPS
Adjust the table HTTPURLLOC to call the URL at WebDispatcher host and port: https://help.sap.com/saphelp_nw70/helpdata/en/42/d547…
SAP Note 2465728
Another post on scn refer to same table.
Maintain an entry in the table HTTPURLLOC with following details:
protocol: https
host: <web despatcher host name>
port: <web despatcher port number>
check in SMICM
Note that
By default we generate URL to the actual backend system where the
content repository is setup. However if web despatcher is being used,
then corresponding settings needs to be done in the system.
check here HTTPURLLOC
https://archive.sap.com/discussions/thread/2059249
I am really curious to find out if someone had this working out-of-box by adjusting values in table HTTPURLLOC. In rest of blog I’ll explain what did worked for me or rather how I made it work.
Employee picture is displayed and uploaded using WebDynpro component HRESS_C_PER_PHOTO. URL to display picture is generated in method PROCESS_BEFORE_OUTPUT of COMPONENTCONTROLLER. Well, within method PROCESS_BEFORE_OUTPUT it make number of calls and eventually call end up in function module HRWPC_RFC_EP_READ_PHOTO_URI which generates the URL. URL is then placed into attribute IMAGE_URL of context node PHOTO. At the end of method PROCESS_BEFORE_OUTPUT of COMPONENTCONTROLLER URL is ready. This is where I put an post-exit method. To replace URL with new URL which use Web Dispatcher URL and Port which was given to me by one of Basis consultant. This port is used in Web Dispacther to redirect call to ContentServer.
Purpose of the code was to generate url
https://mywebdispacther.com:442//ContentServer/ContentServer.dll?get&pVersion=0047&contRep=AB&docId=005056A54E011ED78AD2175760508D…
instead of
http://myerpsys.com:1090//ContentServer/ContentServer.dll?get&pVersion=0047&contRep=AB&docId=005056A54E011ED78AD2175760508D…
Below post exit method read context node, get attribute PHOTO_URL of node and calls method zcl_hr_photo_redirect=>get_redirect_url where URL transformation takes place. If URL transformation is successful, which is returning parameter of method, then it replace new URL in context node’s attributes.
METHOD _pst_00o2tmsr60sq3asdkjaskdjkadjit1 . "Exit of PROCESS_BEFORE_OUTPUT (in ZENHANCEMENT_NAME ) DATA lo_nd_photo TYPE REF TO if_wd_context_node. DATA lo_el_photo TYPE REF TO if_wd_context_element. DATA ls_photo TYPE wd_this->element_photo. DATA lv_image_url TYPE wd_this->element_photo-image_url. DATA lv_incoming_url TYPE string. DATA lv_redirect_url TYPE string. DATA lv_success TYPE boolean. lo_nd_photo = wd_context->get_child_node( name = wd_this->wdctx_photo ). IF lo_nd_photo IS INITIAL. RETURN . ENDIF. lo_el_photo = lo_nd_photo->get_element( ). IF lo_el_photo IS INITIAL. RETURN . ENDIF. lo_el_photo->get_attribute( EXPORTING name = 'IMAGE_URL' IMPORTING value = lv_image_url ). lv_incoming_url = lv_image_url . lv_success = zcl_hr_photo_redirect=>get_redirect_url( EXPORTING incoming_url = lv_image_url IMPORTING ex_redirect_url = lv_redirect_url ). IF lv_success = abap_true . lv_image_url = lv_redirect_url . lo_el_photo->set_attribute( name = 'IMAGE_URL' value = lv_image_url ). ENDIF. ENDMETHOD.
Below is the class method where actual transformation takes place. Logic is based on the interface provided by SAP around table HTTPURLLOC.
CLASS ZCL_HR_PHOTO_REDIRECT DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. CLASS-METHODS GET_REDIRECT_URL IMPORTING !INCOMING_URL TYPE STRING !IV_APPLICATION TYPE CSEQUENCE DEFAULT 'ZPHOTO' EXPORTING !EX_REDIRECT_URL TYPE STRING RETURNING VALUE(EX_SUCCESS) TYPE BOOLEAN . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS ZCL_HR_PHOTO_REDIRECT IMPLEMENTATION. * <SIGNATURE>----------------------------------------------------------------------------------+ * | Static Public Method ZCL_HR_PHOTO_REDIRECT=>GET_REDIRECT_URL * +--------------------------------------------------------------------------------------------+ * | [--->] INCOMING_URL TYPE STRING * | [--->] IV_APPLICATION TYPE CSEQUENCE (default ='ZPHOTO') * | [<---] EX_REDIRECT_URL TYPE STRING * | [<-()] EX_SUCCESS TYPE BOOLEAN * +----------------------------------------------------------------------------------</SIGNATURE> METHOD get_redirect_url. DATA : lt_initial_split TYPE TABLE OF string, ls_initial_split TYPE string. FIELD-SYMBOLS : <lfs_string> TYPE string . DATA in_protocol TYPE string . DATA in_domain TYPE string . DATA in_port TYPE string . DATA out_protocol TYPE string . DATA out_domain TYPE string . DATA out_port TYPE string . DATA def_host TYPE string . DATA url_part TYPE string. DATA host TYPE string. DATA port TYPE string. * FIELD-SYMBOLS : <ls_urltoken> TYPE ty_token . "by default its false ex_success = abap_false . IF incoming_url IS INITIAL . RETURN . ENDIF. "split url into fields SPLIT incoming_url AT '//' INTO TABLE lt_initial_split . * Sanity checks IF lt_initial_split IS INITIAL . RETURN . ENDIF. IF lines( lt_initial_split ) < 3 . RETURN . ENDIF. * Get incoming protocol READ TABLE lt_initial_split INTO ls_initial_split INDEX 1 . in_protocol = ls_initial_split . REPLACE ':' IN in_protocol WITH space . CONDENSE in_protocol . TRANSLATE in_protocol TO UPPER CASE . * Get domain and port READ TABLE lt_initial_split INTO ls_initial_split INDEX 2 . FIND ':' IN ls_initial_split . IF sy-subrc = 0 . SPLIT ls_initial_split AT ':' INTO in_domain in_port . TRANSLATE in_domain TO UPPER CASE . ELSE. in_domain = ls_initial_split . ENDIF. "get default host to indentify missing entry in HTTPURLOC url_part = cl_http_server=>get_location( IMPORTING host = def_host ). TRANSLATE def_host TO UPPER CASE . "get mapping url_part = cl_http_server=>get_location( EXPORTING protocol = in_protocol application = iv_application for_domain = in_domain IMPORTING host = host port = port ). TRANSLATE host TO UPPER CASE . IF def_host = host . "missing mapping RETURN . ENDIF. "extract mapped protocol, domain and port FIND ':' IN host . IF sy-subrc = 0 . SPLIT host AT ':' INTO out_protocol out_domain . REPLACE '//' IN out_domain WITH space . CONDENSE out_domain . ELSE. out_protocol = in_protocol . out_domain = host . ENDIF. out_port = port . "replace in procotol, domain and port with mapped values READ TABLE lt_initial_split ASSIGNING <lfs_string> INDEX 1 . REPLACE in_protocol IN <lfs_string> WITH out_protocol IGNORING CASE . TRANSLATE <lfs_string> TO LOWER CASE . READ TABLE lt_initial_split ASSIGNING <lfs_string> INDEX 2 . FIND ':' IN host . IF sy-subrc = 0 . REPLACE in_domain IN <lfs_string> WITH out_domain IGNORING CASE . REPLACE in_port IN <lfs_string> WITH out_port IGNORING CASE . TRANSLATE <lfs_string> TO LOWER CASE . ELSE. REPLACE in_domain IN <lfs_string> WITH out_domain . TRANSLATE <lfs_string> TO LOWER CASE . ENDIF. "create url using mapped values CLEAR url_part . LOOP AT lt_initial_split INTO ls_initial_split . IF url_part IS INITIAL . url_part = ls_initial_split . ELSE. CONCATENATE url_part ls_initial_split INTO url_part SEPARATED BY '//' . ENDIF. ENDLOOP. IF url_part IS NOT INITIAL . ex_redirect_url = url_part . ex_success = abap_true . ENDIF. ENDMETHOD. ENDCLASS.
For above code to work you need to have this entry in HTTPURLLOC table.
SORT_KEY | PROTOCOL | APPLICATN | FOR_DOMAIN | HOST | PORT |
---|---|---|---|---|---|
100 | HTTP | ZPHOTO | MYERPSYS.COM | HTTPS://MYWEBDISPACHTHER.COM | 442 |
At this point you will notice in Web Dynpro that picture url will now contain new URL. However for this new URL to actually reach your internal server you would need Forwarding Rule in Web Dispatcher (Basis Consultant).
I am afraid this enhancement is a really bad idea. Probably, your problem with HTTPURLLOC and photos was related to table T77TMCPIC_URLS. This table contains photo URLs and works like a cache.
After you change HTTPURLLOC, you should ensure employee photo is not already in this table or you will get an old URL (or at least, check if that URL is out of date – field timestamp).