Skip to Content

Introduction

When using a Portal integrated Launchpad such as ESS/MSS, all navigation requests are handled by Launchpad. In the standard solution the navigation requests are passed to the portal integration API which then invokes the Application Integration implementation included in the ERP Common role. For external URLs the navigation target within the ERP Common role is the iView “Launchpad Start URL” with the ID lpd_start_url. The challenge with the standard implementation is that external URLs will be accessed inside a frame. Most web sites such as Google, Yahoo, etc. do not allow their websites to run inside a frame and even if some web sites do, they might not work properly while accessed in a frame.

 

Solution

To overcome the restriction, implement a replacement iView which redirects to the external URL by using Javascript, bypassing the portal completely. NetWeaver Portal 7.31 SPS08 and ERP 6.0 EHP6 SPS04 were used while implementing this solution.

 

Custom Portal Component

 

Create a new Portal Application Project in NWDS. Within the project create a new Portal Application Object. Choose Portal Component of type AbstractPortalComponent. See below for the coding of doContent().

 

You may be required to add servlet.jar as an External JAR into the build path, especially if you get syntax errors for HttpServletRequest.

 

 

Save, Export and Deploy to AS JAVA.

 

Custom iView

Select the new PRT iView (Copy) from the Portal Content Catalog under folder Portal Applications and create a new iView for it (Paste as PCD Object). Name the new iView “Launchpad Start URL”, technical ID lpd_start_url with the prefix com.sap.pct.erp.common.

 

Modifiying ERP Common role

 

Locate the standard “Launchpad Start URL” iView and remove it from the role. Add the custom iView to the role as a delta link. Now locate the standard iView and add also it as a delta link to the role, the iView will automatically be named lpd_start_url_2.

 

Test and verify

For any URL of type EXTERNAL, a proper redirect should now happen bypassing the portal completely. For all other types of URLs the standard iView (lpd_start_url2) will be called.

 

Comments

 

In the standard Launchpad implementation, navigation paths can’t be easily modified. The paths are contained in table APB_LPD_PATHS. SAP note 1757909 introduces customization table APB_LPD_PATHS_C which can be used to override the navigation paths. Even then having custom navigation types is challenging: at least data types and classes need to be enhanced. The approach I have taken has minimal impact on the back-end system but still a standard portal object needs to be modified which means it must be done again in case of system updates.

 

Source Code

Since the migration from SCN to SAP Community sent attachments into a black hole, I’m including the code for doContent( ) in the blog itself.

 

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import com.sapportals.portal.prt.component.*;

public class Generic extends AbstractPortalComponent {
	@SuppressWarnings("unchecked")
	public void doContent(IPortalComponentRequest request, IPortalComponentResponse response) {
		HttpServletRequest servletRequest = request.getServletRequest();

		if (servletRequest != null) {
			String oldUrl = servletRequest.getRequestURL().toString();

			Enumeration<java.lang.String> parms = servletRequest.getParameterNames();

			String urlTemplate = "";
			String navMode = "";
			String reqMeth = "";
			String windowId = "";
			String relNavBase = "";
			String tarTitle = "";
			String navTarget = "";
			String currWindowId = "";
			String prevNavTarget = "";
			String parmname = "";
			String parmval = "";

			response.write("<!-- BEGIN OF REQUEST PARAMETERS -->\n");

			while (parms.hasMoreElements()) {
				parmname = (String) parms.nextElement();
				parmval = request.getParameter(parmname);

				response.write("<!-- REQUEST PARAMETER: " + parmname + " = " + parmval + "-->\n");

				if (parmname.equals("URLTemplate")) {
					urlTemplate = parmval;
				} else if (parmname.equals("NavMode")) {
					navMode = parmval;
				} else if (parmname.equals("RequestMethod")) {
					reqMeth = parmval;
				} else if (parmname.equals("windowId")) {
					windowId = parmval;
				} else if (parmname.equals("RelativeNavBase")) {
					relNavBase = parmval;
				} else if (parmname.equals("TarTitle")) {
					tarTitle = parmval;
				} else if (parmname.equals("NavigationTarget")) {
					navTarget = parmval;
				} else if (parmname.equals("CurrentWindowId")) {
					currWindowId = parmval;
				} else if (parmname.equals("PrevNavTarget")) {
					prevNavTarget = parmval;
				}
			}

			response.write("<!-- END OF REQUEST PARAMETERS -->\n");

			String newUrl = "";

			if (urlTemplate.length() > 0) {
				if (navMode.equals("1")) {
// redirect to URLTemplate only for URLs of type EXTERNAL
					newUrl = urlTemplate;
				} else {
// for other URL types redirect to standard implementation com.sap.pct.erp.common.lpd_start_url_2
					navTarget = navTarget.replace("com.sap.pct.erp.common.lpd_start_url", "com.sap.pct.erp.common.lpd_start_url_2");
					newUrl = oldUrl + "?RequestMethod=" + reqMeth + "&NavMode=" + navMode + "&URLTemplate=" + urlTemplate + "&windowId=" + windowId + "&RelativeNavBase=" + relNavBase + "&TarTitle="
							+ tarTitle + "&NavigationTarget=" + navTarget + "&CurrentWindowId=" + currWindowId + "&PrevNavTarget=" + prevNavTarget;
				}
				response.write("<script type=\"text/javascript\">\n");
//				response.write("  alert(\"Old URL was " + oldUrl + "\");\n");
//				response.write("  alert(\"Redirecting to URL " + newUrl + "\");\n");
				response.write("  document.location = '" + newUrl + "';\n");
				response.write("</script>\n");
			}
		}
	}
}
To report this post you need to login first.

15 Comments

You must be Logged on to comment or reply to a post.

  1. Hanna A

    Thank you Samuli this is really useful.

    could you mention the list of jar files used for this? I am getting error on

    import javax.servlet.http.HttpServletRequest;

    I am not sure which jar file I need for this.

    Kind regards,

    Hanna

    (0) 
  2. Samuli Kaski Post author

    Hanna A, you probably need to add servlet.jar as an External JAR to the build path. That is at least what I had to do in a vanilla NWDS. In my case servlet.jar was located in the directory C:\eclipse\plugins\com.tssap.ext.libs.j2ee_1.0.0.141205104631\lib.

    (0) 
    1. Hanna A

      Thank you Samuli,

      I actually added that jar file which fixed my previous error but I am now getting could not retrieve portal application error message when I run it in the portal. 

      10:03_16/12/14_0025_482910950

      [EXCEPTION]

      com.sap.portal.prt.broker.PortalModuleNotFoundException: Could not retrieve portal application XXX

      at com.sap.portal.prt.broker.PortalAppBroker.ensurePortalModuleIsStarted(PortalAppBroker.java:640)

      at com.sap.portal.prt.broker.PortalAppBroker.getPortalModule(PortalAppBroker.java:319)

      at com.sap.portal.prt.component.PortalComponentContextFactory.createPortalComponentContext(PortalComponentContextFactory.java:140)

      at com.sap.portal.prt.component.PortalComponentContextFactory.getPortalComponentContext(PortalComponentContextFactory.java:82)

      at com.sap.portal.prt.core.PortalRequestManager.runRequestCycle(PortalRequestManager.java:442)

      at com.sapportals.portal.prt.connection.ServletConnection._handleRequest(ServletConnection.java:224)

      at com.sapportals.portal.prt.connection.ServletConnection.handleRequest(ServletConnection.java:101)

      at com.sap.portal.prt.dispatcher.DispatcherServlet.service(DispatcherServlet.java:132)

      at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

      at com.sap.engine.services.servlets_jsp.server.runtime.FilterChainImpl.runServlet(FilterChainImpl.java:202)

      at com.sap.engine.services.servlets_jsp.server.runtime.FilterChainImpl.doFilter(FilterChainImpl.java:103)

      at com.sap.portal.http.EnrichNavRequestFilter.doFilter(EnrichNavRequestFilter.java:49)

      at com.sap.engine.services.servlets_jsp.server.runtime.FilterChainImpl.doFilter(FilterChainImpl.java:79)

      at com.sap.portal.prt.dispatcher.CustomHeaderFilter.doFilter(CustomHeaderFilter.java:58)

      at com.sap.engine.services.servlets_jsp.server.runtime.FilterChainImpl.doFilter(FilterChainImpl.java:79)

      at com.sap.portal.http.EnrichNavRequestFilter.doFilter(EnrichNavRequestFilter.java:49)

      at com.sap.engine.services.servlets_jsp.server.runtime.FilterChainImpl.doFilter(FilterChainImpl.java:79)

      at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.runServlet(HttpHandlerImpl.java:441)

      at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.handleRequest(HttpHandlerImpl.java:210)

      at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:441)

      at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:430)

      at com.sap.engine.services.servlets_jsp.filters.DSRWebContainerFilter.process(DSRWebContainerFilter.java:38)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.servlets_jsp.filters.ServletSelector.process(ServletSelector.java:81)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.servlets_jsp.filters.ApplicationSelector.process(ApplicationSelector.java:278)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.filters.WebContainerInvoker.process(WebContainerInvoker.java:81)

      at com.sap.engine.services.httpserver.chain.HostFilter.process(HostFilter.java:9)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.filters.ResponseLogWriter.process(ResponseLogWriter.java:60)

      at com.sap.engine.services.httpserver.chain.HostFilter.process(HostFilter.java:9)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.filters.DefineHostFilter.process(DefineHostFilter.java:27)

      at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.filters.MonitoringFilter.process(MonitoringFilter.java:29)

      at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.filters.SessionSizeFilter.process(SessionSizeFilter.java:26)

      at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.filters.MemoryStatisticFilter.process(MemoryStatisticFilter.java:57)

      at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.filters.DSRHttpFilter.process(DSRHttpFilter.java:43)

      at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)

      at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)

      at com.sap.engine.services.httpserver.server.Processor.chainedRequest(Processor.java:475)

      at com.sap.engine.services.httpserver.server.Processor$FCAProcessorThread.process(Processor.java:269)

      at com.sap.engine.services.httpserver.server.rcm.RequestProcessorThread.run(RequestProcessorThread.java:56)

      at com.sap.engine.core.thread.execution.Executable.run(Executable.java:122)

      (0) 
      1. Samuli Kaski Post author

        What do you mean by running it? Can you preview the iView using the custom portal component without problems? You shouldn’t be able to create the iView if the deployment of the custom portal component hasn’t been successful, at least not the way you are supposed to create it (under Portal Applications, Copy & Paste as PCD object).

        (0) 
        1. Hanna A

          I meant when I tried to open the url link  but I just found out that in the url lunchpad I used portal page instead of URL. I fixed that and it works now. thank you, your solution helps 🙂

          (0) 
  3. Prashanth Nanjappa

    Hello Samuli,

    Thanks for sharing this here. Can you suggest what changes are required to open a link in a new tab instead of a new window on IE specifically if that matters.

    Thanks in advance for your help!

    Prashanth

    (0) 
    1. Samuli Kaski Post author

      I think that is more a question of how the browser opens new windows. I believe tabbed browsing became the default in IE8, it can also be configured in the browser settings if not set currently. To force it in code, you can try to use the _new target or one of the other known workarounds. There are many discussions about workarounds for example on Stack Overflow.

      (0) 
  4. JagadishBabu nagarapu

    Hi Samuli,

    Thanks for sharing the blog on external links. We have a requirement to open the links in a new tab instead of new window. When we try to proposed solution it is not getting reflected in the portal. we tried to trace using HTTPWATCH the links calling the script from

    http://****************/sap/public/bc/ur/nw7/js/classes/IHubNavigation.js

    but we couldn’t find the place holder for the java script in ABAP side.

    Please let us know how can we make the links open in new tab.

    regards,

    Jagadishbabu

    (0) 
    1. Samuli Kaski Post author

      My solution is totally client based, the redirect is done by Javascript. The only functionality that is invoked in the backend is the launchpad part which triggers the portal object for launching the new window. Unfortunately without knowing more of your configuration, I can’t help. I suggest you create a new discussion thread in the appropriate space to get help. Enclose as much detail as possible.

      (0) 
  5. David Uztariz

    Hello Samuki.

    I am using your approach for SAP SRM External Catalogs. I followed all steps, but the result is that the actual iview is Ipd.start_url_2 is being executed instead of the custom one.

    I get the HTTP:500 error. Please advice.

    (0) 
      1. Kumar V

        Hi Samuki,

        We have tried above mentioned solution and when we try to open the external Catalog we are receiving error as ” sap/sapsrm/outbound_hdlr was terminated because of an error. “.

        Error Details:

        Error while processing your query

        What has happened?

        The URL call https://localhost.net/sap/sapsrm/outbound_hdlr was terminated because of an error.

         

        Note

        The following error occurred in system : Buffer table not up-to-date

        The error occurred on application server and in work process. 3

        The termination type was: RABAX_STATE

        The ABAP call stack was:

        Function: BBP_PD_ABORT of program SAPLBBP_PDH

        Method: GET_BACK_URL of program /SAPSRM/CL_CH_WD_OUTBOUND_HDLRCP

        Method: RENDER_BACK_LINK of program /SAPSRM/CL_CH_WD_OUTBOUND_HDLRCP

        Method: IF_HTTP_EXTENSION~HANDLE_REQUEST of program /SAPSRM/CL_CH_WD_OUTBOUND_HDLRCP

        Method: EXECUTE_REQUEST of program CL_HTTP_SERVER================CP

        Function: HTTP_DISPATCH_REQUEST of program SAPLHTTP_RUNTIME

        Module: %_HTTP_START of program SAPMHTTP

        Kindly let us know how to proceed further on this.

        Thanks & Regards,

        Mahesh Kumar.

        (0) 

Leave a Reply