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

how to access a servlet from an OSGI component?

  • May 19, 2025
  • 2 の返信
  • 617 ビュー

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.

 

2 の返信

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();