how to access a servlet from an OSGI component? | Community
Skip to main content
jayv25585659
Level 8
May 19, 2025

how to access a servlet from an OSGI component?

  • May 19, 2025
  • 2 replies
  • 621 views

as above.

 

  • The servlet would be of class org.apache.sling.api.servlets.SlingSafeMethodsServlet.
  • The OSGI component would be of org.osgi.service.component.annotations.Component.

Thank you.

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

2 replies

Peter_Puzanovs
Community Advisor
Community Advisor
May 19, 2025

Hi Jay,

 

AEM provides us with SlingRequestDispatcher[1],

This would allow you to fire request from within your component code.

 

Following reply from the past seems to help too[2]

 

1 [https://github.com/apache/sling-org-apache-sling-engine/blob/master/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java]

2 [https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/dispatch-request-to-a-page-component-from-servlet/m-p/216782] 


Regards,

Peter

AmitVishwakarma
Community Advisor
Community Advisor
May 20, 2025

Hi @jayv25585659 ,

Try below solutions:

Solution1: Use SlingRequestDispatcher (internal request)

Servlet (Example)

@Component(service = Servlet.class, property = { "sling.servlet.methods=GET", "sling.servlet.paths=/bin/myservlet" } ) public class MyExampleServlet extends SlingSafeMethodsServlet { @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { response.getWriter().write("Hello from Servlet!"); } }

2. OSGi Component (Calling the Servlet Internally)

@Component(immediate = true, service = Runnable.class) public class ServletCallerComponent implements Runnable { @Reference private SlingRequestProcessor requestProcessor; @Reference private ResourceResolverFactory resourceResolverFactory; @Override public void run() { try (ResourceResolver resolver = resourceResolverFactory .getServiceResourceResolver(Collections.singletonMap( ResourceResolverFactory.SUBSERVICE, "my-service-user"))) { HttpServletRequest request = new DummySlingHttpServletRequest(resolver, "/bin/myservlet"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); HttpServletResponse response = new DummySlingHttpServletResponse(outputStream); requestProcessor.processRequest(request, response, resolver); String servletOutput = outputStream.toString(StandardCharsets.UTF_8.name()); System.out.println("Servlet Response: " + servletOutput); } catch (Exception e) { e.printStackTrace(); } } }

3. Helper Dummy Request/Response Classes

Use mock implementations or leverage Sling Mocks in testing. But for real-world use, create minimal functional mock objects or invoke via external HttpClient.

Solution2: Use HttpClient (external HTTP call)

@Activate public void activate() { try (CloseableHttpClient client = HttpClients.createDefault()) { HttpGet request = new HttpGet("http://localhost:4502/bin/myservlet"); CloseableHttpResponse response = client.execute(request); String body = EntityUtils.toString(response.getEntity()); System.out.println("Servlet Output: " + body); } catch (IOException e) { e.printStackTrace(); } }

Use only if external HTTP call is acceptable (e.g., running on the same server or across instances). Otherwise prefer internal dispatch.

Regards,
Amit

 

Imran Khan
Community Advisor
Community Advisor
May 20, 2025

@jayv25585659 To follow best practice, create a service that holds the business logic and inject that service both into the servlet and your OSGi component.

 

If it is really required, than use below HTTP call to servlet:

URL url = new URL("http://localhost:4502/bin/myservlet");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStream responseStream = connection.getInputStream();