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

18,631

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.

Share:
18,631
mitchj
Author by

mitchj

Updated on June 12, 2022

Comments

  • mitchj
    mitchj about 2 years

    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");
        }
    }
    
  • mitchj
    mitchj over 9 years
    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.
  • Bertrand Delacretaz
    Bertrand Delacretaz over 9 years
    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.
  • Sharath Madappa
    Sharath Madappa over 9 years
    @BertrandDelacretaz , thanks for pointing it. Changed the code
  • Sri
    Sri over 8 years
    Can any one of you answer this question : stackoverflow.com/questions/35076684/…
  • Josh Boyle
    Josh Boyle over 7 years
    Excellent and clear answer here. Well done, Sharath.