Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

How to get the current pagepath in service

Avatar

Level 4

I have used the below code to get the currentpagepath in modal but if I use same code in service it is not working nd currentpage value I am getting null. Can anyone help on this.

 

@ScriptVariable
protected Page currentPage;

 

public string getCurrenPath() {

String currentPagePath = currentPage.getPath();

return currentPagePath;

}

1 Accepted Solution

Avatar

Correct answer by
Level 8

You need to pass the current page object to the OSGi service.

public void readProperties(Page currentPage) {
ResourceResolver resolver = null;
InheritanceValueMap map = new HierarchyNodeInheritanceValueMap(currentPage.getContentResource());
}

In the sling model call OSGI service

  @Inject @Source("osgi-services")
  TestService testService1;

    @PostConstruct
    public void activate(){
        System.out.println("Inside Post Constructor Method");
        testService1.readProperties(currentPage);
    }

You can also pass page path as a parameter to the service method and inside service method, you need to write something like this

@reference
private ResourceResolverFactory resolverFactory;

public void testMethod(String resourcePath ) {
try {

Resource res = resourceResolver.getResource(resourcePath);

resourceResolver.close();
} catch (LoginException e) {
// log the error
}
}

 

 

View solution in original post

16 Replies

Avatar

Community Advisor

@vijitha 

You can not use Sling annotations in OSGI service. currentPage, currentNode etc.. are global sling objects which will be created while Sling resolving particular resource. As Sling model has all the capabilities of Sling, those variables/objects will be directly injected in to Sling Model in context of current request.

In OSGI service this is not that straight forward, you should get the current Page and then get path.

  • Get the ResourceResolver
  • Get current Resource
  • Adapt resourceResolver to PageManager
  • Get the current Page by passing current resource
  • Get path from Page

Try the below code snippet, might help. Here I am getting Resource and ResourceResolver from request.

PageManager pageManager = request.getResourceResolver().adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(request.getResource());
String pagePath = currentPage.getPath();

 

Avatar

Level 4

Hi @Anudeep_Garnepudi Thank you for the detailed explanation. I have tried using the above code but I am getting null value in request in service.

 

SlingHttpServletRequest request;

path.PNG

Avatar

Community Advisor
@vijitha In my example I am using Servlet configured with a component resource type. I dropped that component in a page and hitting that component path. The registered servlet with take the request in context of that component and will return the page path in which component is dropped. Please let me know what exactly your use case is.

Avatar

Level 3

I'm also getting the null value for the currentPage if I tried following the same code snippet which you have posted. 

My use case is I'm triggering the servlet call on click of a button in a component. Now I need the currentPage in which the component is placed. 

I'm getting null value because the I have configured my servlet request whose path is inside /etc which doesn't have the direct link to the page.

Could u suggest any work around for this scenario.

Avatar

Level 3

Hi @Rajalakshmi 


There is one way to do this, expose ${currentPage.path} in the component's sightly and ask FE to send it as part of request body (dont do as query param). So once you have it in the servlet you can use it accordingly. Hope this helps.

Avatar

Level 4

Hi @Anudeep_Garnepudi @Manjunath_K, In my case I have one method in service and that method we are calling in multiple Model files.If I pass request as method argument in modal I am able to get the current page path.Dow have any option with out changing code in modal. I have tried as per your suggestions its working fine. 

****************working *************
public class TestModal1 {
@Override
public LinkItem getLinkItem() { return testLinkService.getLinkItem(Url, true, request); }
}

public class TestModal2 {
@Override
public LinkItem getLinkItem() { return testLinkService.getLinkItem(Url, true, request); }
}


public class testLinkService {
@Override
public LinkItem getLinkItem(final String url, final boolean isFragment,SlingHttpServletRequest request)
{
PageManager pageManager = request.getResourceResolver().adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(request.getResource());
String pagePath = currentPage.getPath();
if (path.contains("****") ) {
linkItem.setTarget("_parent");
}
}
}
****************working *************

Do we have any other option instead of changing model code.Since I am using that getLinkItem method in mutple models.

****************not working *************
public class TestModal1 {
@Override
public LinkItem getLinkItem() { return testLinkService.getLinkItem(Url, true); }
}

public class TestModal2 {
@Override
public LinkItem getLinkItem() { return testLinkService.getLinkItem(Url, true); }
}


public class testLinkService {
@Override
public String getPath(final SlingHttpServletRequest request) {
PageManager pageManager = request.getResourceResolver().adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(request.getResource());
String pagePath = currentPage.getPath();
return pagePath;
}
public LinkItem getLinkItem(final String url, final boolean isFragment) {
String path= getPath(request); ----if i declare local varable in this method i need intialize here if i intialize it will take null value ----
if (path.contains("****") ) {
linkItem.setTarget("_parent");
}
}
}
****************not working *************

Avatar

Level 8

Hi @vijitha

To get current page path in OSGI service method, we need current request. so, passing method argument to service class methods is the only way with below 2 option.

 

1. Recommended approach - duplicating code in each model class to fetch current page path before passing it to service methods will be reduced if you keep that logic in service methods by passing request as method argument.

public class TestModal1 {
@Override
public LinkItem getLinkItem() {
         

       return testLinkService.getLinkItem(Url, true, request); }
}

 

public class TestLinkService {
@Override
public LinkItem getLinkItem(final String url, final boolean isFragment,SlingHttpServletRequest request)
{
            //get current page path using current request 
}

}

 

2.

public class TestModal1 {
@Override
public LinkItem getLinkItem() {

          //get current page path using current request & pass page path to service methods.

          return testLinkService.getLinkItem(Url, true, currentPagePath); }
}

 

public class TestLinkService {
@Override
public LinkItem getLinkItem(final String url, final boolean isFragment,String currentPagePath)
{

}

}

Avatar

Community Advisor

@vijitha, No other way you need to update you Service and Sling Models. Better get the current page path in Sling Model and passing it as an argument to your service and update your Service accordingly.

//Service
String getLinkItem(final String url, final boolean isFragment,String pagePath) {
 ...
}
// Service Call in Sling Model
testLinkService.getLinkItem(Url, true, currentPage.getPath());

 

Avatar

Community Advisor

In Service you have to user ResourceResolver , Resource objects

 

ResourceResolver resourceResolver = request.getResourceResolver();

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);

Page currentPage = pageManager.getPage("/content/page/en/");

Avatar

Correct answer by
Level 8

You need to pass the current page object to the OSGi service.

public void readProperties(Page currentPage) {
ResourceResolver resolver = null;
InheritanceValueMap map = new HierarchyNodeInheritanceValueMap(currentPage.getContentResource());
}

In the sling model call OSGI service

  @Inject @Source("osgi-services")
  TestService testService1;

    @PostConstruct
    public void activate(){
        System.out.println("Inside Post Constructor Method");
        testService1.readProperties(currentPage);
    }

You can also pass page path as a parameter to the service method and inside service method, you need to write something like this

@reference
private ResourceResolverFactory resolverFactory;

public void testMethod(String resourcePath ) {
try {

Resource res = resourceResolver.getResource(resourcePath);

resourceResolver.close();
} catch (LoginException e) {
// log the error
}
}

 

 

Avatar

Community Advisor

Hi @vijitha,

 

As per your comments, assuming you have request object, you can get the page URL like this:

Enumeration values = request.getHeaders(REFERER);

while (values.hasMoreElements()) {
pageURL = values.nextElement().toString();
}

Once you get the URL, you can trim it and fetch the path.

 

Hope this helps.

 

Thanks,

Kiran Vedantam.

Avatar

Level 8

Hi @vijitha ,

1. If you want to get current page path in OSGI Service class then pass request as an method argument to service class methods from model/servlet class & get page path using request present in the method parameter. 

 

2. If you want to get current page path in servlet then you can get it using code shared by @Anudeep_Garnepudi.

 

Hope this helps!

Avatar

Level 8

Hi @vijitha

To get current page path in OSGI service method, we need current request. so, passing method argument to service class methods is the only way with below 2 option.

 

1. Recommended approach - duplicating code in each model class to fetch current page path before passing it to service methods will be reduced if you keep that logic in service methods by passing request as method argument.

public class TestModal1 {
@Override
public LinkItem getLinkItem() {
         

       return testLinkService.getLinkItem(Url, true, request); }
}

 

public class TestLinkService {
@Override
public LinkItem getLinkItem(final String url, final boolean isFragment,SlingHttpServletRequest request)
{
            //get current page path using current request 
}

}

 

2.

public class TestModal1 {
@Override
public LinkItem getLinkItem() {

          //get current page path using current request & pass page path to service methods.

          return testLinkService.getLinkItem(Url, true, currentPagePath); }
}

 

public class TestLinkService {
@Override
public LinkItem getLinkItem(final String url, final boolean isFragment,String currentPagePath)
{

}

}

Avatar

Administrator
@Manjunath_K, thank you for sharing the answer. This would help AEM Community in posterity. Keep doing the great work in the AEM community.


Kautuk Sahni

Avatar

Community Advisor

@vijitha 

Assuming that your problem is from Sling Models...

There two be really important declarations you are not sharing.

What is the adaptables? Make sure the SlingHttpServletRequest.class value is an adaptable option

What is the actual Page object you are referencing to? making sure com.day.cq.wcm.api.Page object is being referenced.

I tested the code below and it works for me:

 

@Model(adaptables = {SlingHttpServletRequest.class},
        defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class Component {
    @ScriptVariable
    private com.day.cq.wcm.api.Page currentPage;
}