How to invoke Sling Servlet that uses "resourceType" instead of "paths" in @SlingServlet annotation
Asked Answered
G

1

5

How do I invoke a Sling Servlet that uses the "resourceType" property inside @SlingServlet? When I use"paths" I just call it with an ajax call but I am not sure what to do if I change my servlet to use "resourceType" instead of "paths". (I am making the change for learning purposes)

I am still learning CQ5, Sling, etc.

My servlet follows.

package com.mypackage.weather;

import org.apache.sling.api.resource.*;
import org.apache.sling.commons.osgi.PropertiesUtil;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import javax.servlet.ServletException;
import java.io.BufferedReader;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SlingServlet(
        name="Weatherservlet",
        //paths="/bin/Weather",
        resourceType="OpenWeather/components/page/contentPage",
        methods="GET",
        metatype=true)
@Properties({
        @org.apache.felix.scr.annotations.Property(name="WeatherServlet", description="Get JSON String weather info", value="mitch weather"),
        @org.apache.felix.scr.annotations.Property(name = "apikey", label = "The api key", value = "d8e39388b0bc54a62ffc6b385639b3dc") // register the api key in the OSGi console
})

/**
 * Handles requests for getting weather information from OpenWeatherMap.org.  returns the information as a JSon string.
 */
public class WeatherServlet extends SlingSafeMethodsServlet {

    private static final String SERVER = "localhost:4502";
    private static final String RESOURCE_PATH = "/content/OpenWeather";
    private String apikey = "";
    private String location = "";
    private ResourceResolver resourceResolver;

    private Logger logger = LoggerFactory.getLogger(WeatherServlet.class);

    @Override
    public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        logger.info("Reconfigured Weather Servlet");
        getWeather(request, response);

    }

    /**
     * Gets current weather information from OpenWeatherMap.org API
     * @param request
     * @param response
     * @throws IOException
     */
    public void getWeather(SlingHttpServletRequest request, SlingHttpServletResponse response)   {
        logger.info("api key: " + apikey);
        location = request.getParameter("city");
        logger.info("city sent: " + location);
        String urlString = "http://api.openweathermap.org/data/2.5/weather?q=" + location + "&units=imperial&APPID=" + apikey;
        logger.info("urlString: " + urlString);
        URL url = null;
        HttpURLConnection connection = null;
        int responseCode = -9;
        String result = "";
        logger.info("Before call to Open Weather");
        long startTime = System.currentTimeMillis();
        try {
            url = new URL(urlString);
            logger.info("url: " + url);
            connection = (HttpURLConnection) url.openConnection();
            logger.info("Connection: " + connection);
            connection.setRequestMethod("GET");
            responseCode = connection.getResponseCode();
            logger.info("After calling Open Weather");
            BufferedReader reader;
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            logger.info("reader: " + reader);
            result = reader.readLine();
            long stopTime = System.currentTimeMillis();
            long elapsedTime = stopTime - startTime;
            logger.info("Elapsed Time is... " + elapsedTime);
            logger.info("result: " + result);
            PrintWriter writer = response.getWriter();
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            writer.write(result);
        } catch (MalformedURLException e) {
            logger.info("MalformedURL");
            e.printStackTrace();
        } catch (IOException e) {
            logger.info("IOException!!!!!!!!");
            e.printStackTrace();
            logger.info("Cause: " + e.getCause());
        }
    }


    protected void activate(ComponentContext context)
    {
        apikey = PropertiesUtil.toString(context.getProperties().get("apikey"), "d8e39388b0bc54a62ffc6b385639b3dc"); // Get the api key from the OSGi console
        System.out.println("weather servlet activated");
    }
}
Germayne answered 17/3, 2015 at 14:50 Comment(0)
C
11

Instead of making ajax call to the path in the servlet, you make an ajax call to the component. In case you want the servlet to work with resourceType the servlet should have an additional configuration for extensions property (sling.servlet.extensions).This configuration let's you run a servlet in context of a resource(of a particular resourceType) instead of a global one.

Let me explain with an example. Consider a page content/home.html with a foo component (resourceType="/apps/someproject/components/foo) at path /par/foo . Normally on a page the component will be requested with .html selector and the resource will be rendered by the default script (foo.jsp). Let's add a servlet with the following annotation

@SlingServlet( name="Weatherservlet", extensions = "pdf", resourceType="someproject/components/foo", methods="GET", metatype=true) which will give pdf representation of the resource.

A GET request to /content/home/jcr:content/par/foo.pdf will be handled by the servlet instead of foo.jsp.

request.getResource() inside the servlet's doGet will return the component resource.

path configuration will override the resourceType configuration.

Condorcet answered 17/3, 2015 at 15:12 Comment(5)
Thank you very much! Your answer along with a colleague's is helping me to more fully understand how to do Sling servlets with resourceType.Germayne
Note that absolute resource types like /apps/someproject/components/foo are not recommended, you should use someproject/components/foo in this case. /apps is a prefix defined by the Sling resolver configuration, which could change in the future.Paramour
@BertrandDelacretaz , thanks for pointing it. Changed the codeCondorcet
Can any one of you answer this question : #35077184Weidar
Excellent and clear answer here. Well done, Sharath.Restharrow

© 2022 - 2024 — McMap. All rights reserved.