Retrieve servletContext reference in quartz scheduler

为君一笑 提交于 2019-11-27 23:18:54
Boro

I had a similar need. I sorted it out in a similar fashion to the solution presented here. In my servlet context listener I am setting the servlet context using the job data map object which then is set for a job:

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        try {
            //Create & start the scheduler.
            StdSchedulerFactory factory = new StdSchedulerFactory();
            factory.initialize(sce.getServletContext().getResourceAsStream("/WEB-INF/my_quartz.properties"));
            scheduler = factory.getScheduler();
            //pass the servlet context to the job
            JobDataMap jobDataMap = new JobDataMap();
            jobDataMap.put("servletContext", sce.getServletContext());
            // define the job and tie it to our job's class
            JobDetail job = newJob(ImageCheckJob.class).withIdentity("job1", "group1").usingJobData(jobDataMap).build();
            // Trigger the job to run now, and then repeat every 3 seconds
            Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow()
                  .withSchedule(simpleSchedule().withIntervalInMilliseconds(3000L).repeatForever()).build();
            // Tell quartz to schedule the job using our trigger
            scheduler.scheduleJob(job, trigger);
            // and start it off
            scheduler.start();
        } catch (SchedulerException ex) {
            log.error(null, ex);
        }
    }

Then inside my job I am doing this:

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        ServletContext servletContext = (ServletContext) context.getMergedJobDataMap().get("servletContext");
        //...
    }

EDIT: Also since you mention that you are using Spring I found this link, where in the last post a guy mentions to implement ServletContextAware. Personally, I would go with the JobDataMap, since that is its role.

Starting from Quartz 2.0, if you are starting the scheduler inside your webapp via QuartzInitializerServlet in your web.xml, you can store ServletContext in your SchedulerContext by setting scheduler-context-servlet-context-key as an init parameter as follows:

<!-- Quartz Scheduler Initializer Servlet -->
<servlet>
    <servlet-name>QuartzInitializer</servlet-name>
    <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
    <init-param>
        <param-name>shutdown-on-unload</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>start-scheduler-on-load</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>scheduler-context-servlet-context-key</param-name>
        <param-value>servletContext</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

See the following reference in code: https://github.com/elventear/quartz-scheduler/blob/quartz-2.0.0-rc/quartz/src/main/java/org/quartz/ee/servlet/QuartzInitializerServlet.java#L122

To get to your ServletContext from a QuartzJob configure like Kalman said, Then here is some code to get a actual "servletContext"

private void initContext(JobExecutionContext jobContext) {

    Scheduler scheduler = jobContext.getScheduler();
    SchedulerContext schedulerContext = null;
    try {
        schedulerContext = scheduler.getContext();
    } catch (SchedulerException e) {
        e.printStackTrace();
    }

     ServletContext servletContext = (ServletContext)schedulerContext.get("servletContext");
     System.out.println("ServletContextName : "+  servletContext.getServletContextName());
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!