Get ServletContext in Application

前端 未结 6 688
长情又很酷
长情又很酷 2020-12-29 07:06

Could you possibly explain how I can get the ServletContext instance in my Application\'s sub-class? Is it possible? I have tried to do it like in

相关标签:
6条回答
  • 2020-12-29 07:24

    Don't use @Context in your Application but in a Resource class.

    @Path("/foos")
    public class FooResource {
    
      @Context
      ServletContext ctx;
    
      @GET
      public Response getFoos() {
        return Response.ok().build();
      }
    }
    
    0 讨论(0)
  • 2020-12-29 07:27

    Injection happens when you enter service method. Check if this is a problem.

    0 讨论(0)
  • 2020-12-29 07:28

    You can use the ApplicationEventListener interface to get the ServletContext. After initialization has finished, you can 'catch' an ApplicationEvent and use the injected ServletContext to work with.

    Works fine with: org.glassfish.jersey : 2.12
    For additional versions, pls use comments - i dont know, sry.

    Jersey Docs - 20.1.2. Event Listeners

    Your MainApplication:

    @ApplicationPath("/")
    public class MainApplication extends Application {
        @Override
        public Set<Class<?>> getClasses() {     
            Set<Class<?>> set = new HashSet<Class<?>>();
            set.add(MainApplicationListener.class);
            return classes;
        }
    }
    

    ... or alternative MainResourceConfig (I prefer to use this one):

    public class MainResourceConfig extends ResourceConfig {
        public MainResourceConfig() {
            register(MainApplicationListener.class);
        }
    }
    

    And the ApplicationEventListener:

    public class MainApplicationListener implements ApplicationEventListener {
    
        @Context
        private ServletContext ctx; //not null anymore :)
    
        @Override
        public void onEvent(ApplicationEvent event) {
            switch (event.getType()) {
                case INITIALIZATION_FINISHED:
                // do whatever you want with your ServletContext ctx
                break;
        }
    
        @Override
        public RequestEventListener onRequest(RequestEvent requestEvent) {
            return null;
        }
    
    }
    
    0 讨论(0)
  • 2020-12-29 07:30

    There is interesting statement in documentation for Jersey version 1.18 for class com.sun.jersey.spi.container.servlet.ServletContainer

    The servlet or filter may be configured to have an initialization parameter "com.sun.jersey.config.property.resourceConfigClass" or "javax.ws.rs.Application" and whose value is a fully qualified name of a class that implements ResourceConfig or Application. If the concrete class has a constructor that takes a single parameter of the type Map then the class is instantiated with that constructor and an instance of Map that contains all the initialization parameters is passed as the parameter.

    If my understanding is correct the following constructor must be invoced with "an instance of Map that contains all the initialization parameters"

    public class ExampleApplication extends Application {
        public ExampleApplication(Map initParams) {
        }
        ...
    }
    

    Here is appropriate part of web.xml:

    <servlet>
      <servlet-name>Jersey Web Application</servlet-name>
      <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
           <param-name>javax.ws.rs.Application</param-name>
           <param-value>experiment.service.ExampleApplication</param-value>
        </init-param>
    </servlet>
    

    But somehow it failed for me with the following message:

    SEVERE: Missing dependency for constructor public experiment.service.ExampleApplication(java.util.Map) at parameter index 0

    And for current version of Jersey (2.5.1) there are no such statement in documentstion: https://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/servlet/ServletContainer.html

    0 讨论(0)
  • 2020-12-29 07:31

    Since Jersey 2.5, ServletContext can be injected directly in constructor: https://java.net/jira/browse/JERSEY-2184

    public class MyApplication extends ResourceConfig {
        public MyApplication(@Context ServletContext servletContext) {
           // TODO
        }
    }
    
    0 讨论(0)
  • 2020-12-29 07:31

    @Context can be made available on ResoureConfig by injecting it as a constructor parameter using @Context. Another way to access it is through an event handler.

    Try the below code.

    @ApplicationPath("...")
    public class MyApplication extends ResourceConfig {
        public MyApplication() {
            register(StartupHandler.class);
        }
    
        private static class StartupHandler extends  AbstractContainerLifecycleListener {
            @Context
            ServletContext ctx;
    
            @Override
            public void onStartup(Container container) {
                // You can put code here for initialization. 
            }
        }
    // ...
    
    0 讨论(0)
提交回复
热议问题