Search code examples
javajettyrestlet

How to set attributes on Application Context through a Jetty server Handler


I set up a Jetty server and bind it to a Restlet Application :

                    server = new org.eclipse.jetty.server.Server(PORT);

                    final ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
                    servletContext.setContextPath("/");
                    servletContext.setInitParameter("org.restlet.application", MyApplication.class.getName());
                    servletContext.addServlet(ServerServlet.class, "/*");
                    servletContext.addServlet(DefaultServlet.class, "/");

                    server.setHandler(servletContext);
                    server.start();
                    server.join();

However I want to set some attribute to the Application context. How to manage that. I tried this but it does not do the trick, and I fear I am awfully misundertanding how the Restlet Context is handled is such case...

    servletContext.setAttribute("agent", this);

It keeps giving an empty Context in MyApplication(Context parentContext) call...

I am lost there. How can I give software context to my Restlet Application in this case ?


Solution

  • After having a look into the source code (see https://github.com/restlet/restlet-framework-java/blob/master/modules/org.restlet.ext.servlet/src/org/restlet/ext/servlet/ServerServlet.java#L947), it appears that both init parameters from servlet config and servlet context are copied in the Restlet application context within its parameters list.

    So you can pass parameters from servlet context to the Restlet application context. Here is a sample:

    • Defining the parameter when configuring the servlet context

      final ServletContextHandler servletContext
         = new ServletContextHandler(ServletContextHandler.SESSIONS);
      servletContext.setContextPath("/");
      
      servletContext.setInitParameter(
        "org.restlet.application", MyApplication.class.getName());
      servletContext.setInitParameter("test", "my param"); <-----------
      
      servletContext.addServlet(ServerServlet.class, "/*");
      servletContext.addServlet(DefaultServlet.class, "/");
      
    • Getting the parameter within the Restlet application class

      public class MyApplication extends Application {
          public MyApplication () {
              super();
          }
      
          @Override
          public Restlet createInboundRoot() {
              Series<Parameter> parameters = getContext().getParameters();
              for (Parameter parameter : parameters) {
                  System.out.println("- parameter = "+parameter);
              }
      
              (...)
          }
      }
      

    There is also another (but intrusive) approach since Restlet keeps an instance on the ServletContext within the application context. This allows to pass objects not only string ones. Here is a sample:

    • Defining the parameter when configuring the servlet context

      final ServletContextHandler servletContext
        = new ServletContextHandler(ServletContextHandler.SESSIONS);
      servletContext.setContextPath("/");
      
      servletContext.setAttribute("myAttr", new ArrayList<>());
      
      servletContext.addServlet(ServerServlet.class, "/*");
      servletContext.addServlet(DefaultServlet.class, "/");
      
    • Getting the parameter within the Restlet application class

      public class MyApplication extends Application {
          public MyApplication () {
              super();
          }
      
          @Override
          public Restlet createInboundRoot() {
              ServletContext context
                = (ServletContext) getContext().getAttributes().get(
                        "org.restlet.ext.servlet.ServletContext");
              List l = (List) context.getAttribute("myAttr");
              (...)
          }
      }
      

    Hope it helps you, Thierry