Expand my Community achievements bar.

Introducing Adobe LLM Optimizer: Own your brand’s presence in AI-Powered search and discovery

how to access a servlet from an OSGI component?

Avatar

Level 9

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.

 

4 Replies

Avatar

Community Advisor

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/e...]

2 [https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/dispatch-request-to-a-page... 


Regards,

Peter

Avatar

Community Advisor

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

 

Avatar

Community Advisor

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

Avatar

Level 2

This will work