Quartzジョブを手動で起動する方法(JSF 2の例)
Quartzでは、以下のパターンで手動でジョブをトリガできます:
JobKey jobKey = new JobKey(jobName, jobGroup); scheduler.triggerJob(jobKey);//trigger a job by jobkey
このチュートリアルでは、JSF 2 Webアプリケーションを表示し、 `dataTable`にすべてのQuartzジョブを表示し、ユーザーがリンクをクリックして手動でジョブを起動できるようにします。
使用されたツール:
-
JSF 2.1.11
-
クォーツ2.1.5
-
Eclipse 4.2
-
Maven 3
-
Tomcat 6と7でテスト済み
1.プロジェクトディレクトリ
最終プロジェクトディレクトリ。
プロジェクトの依存関係
このチュートリアルのすべての依存関係
File:pom.xml
<project ...> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.1.11</version> </dependency> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-impl</artifactId> <version>2.1.11</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> </dependency> <!-- solve method not found error in tomcat --> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>el-impl</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>com.sun.el</groupId> <artifactId>el-ri</artifactId> <version>1.0</version> </dependency> <!-- Quartz scheduler framework --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.1.5</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency> </dependencies> </project>
3.クォーツジョブ
2つのジョブを作成し、リスナーを介して ‘web.xml’にJSFと統合します。
package com.mkyong.jobs; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class JobA implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Job A is runing"); } }
package com.mkyong.jobs; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class JobB implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Job B is runing"); } }
ファイル:quartz.properties
org.quartz.scheduler.instanceName = MyScheduler org.quartz.threadPool.threadCount = 3 org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore org.quartz.plugin.jobInitializer.class =org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin org.quartz.plugin.jobInitializer.fileNames = quartz-config.xml org.quartz.plugin.jobInitializer.failOnFileNotFound = true
ファイル:quartz.config
<?xml version="1.0" encoding="UTF-8"?> <job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job__scheduling__data__1__8.xsd" version="1.8"> <schedule> <job> <name>JobA</name> <group>GroupDummy</group> <description>This is Job A</description> <job-class>com.mkyong.jobs.JobA</job-class> </job> <trigger> <cron> <name>dummyTriggerNameA</name> <job-name>JobA</job-name> <job-group>GroupDummy</job-group> <!-- It will run every 30 seconds --> <cron-expression>0/30 ** ** ** ** ?</cron-expression> </cron> </trigger> </schedule> <schedule> <job> <name>JobB</name> <group>GroupDummy</group> <description>This is Job B</description> <job-class>com.mkyong.jobs.JobB</job-class> </job> <trigger> <cron> <name>dummyTriggerNameB</name> <job-name>JobB</job-name> <job-group>GroupDummy</job-group> <!-- It will run every 30 seconds --> <cron-expression>0/30 ** ** ** ** ?</cron-expression> </cron> </trigger> </schedule> </job-scheduling-data>
File:web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app__2__5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app__2__5.xsd" id="WebApp__ID" version="2.5"> <display-name>JavaServerFaces</display-name> <!-- Change to "Production" when you are ready to deploy --> <context-param> <param-name>javax.faces.PROJECT__STAGE</param-name> <param-value>Development</param-value> </context-param> <!-- Welcome page --> <welcome-file-list> <welcome-file>faces/welcome.xhtml</welcome-file> </welcome-file-list> <!-- JSF mapping --> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- Map these files with JSF --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/** </url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>** .jsf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>** .faces</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>** .xhtml</url-pattern> </servlet-mapping> <listener> <listener-class> org.quartz.ee.servlet.QuartzInitializerListener </listener-class> </listener> </web-app>
4. JSF Bean
後で `dataTable`のデータを提供するJSF beanです。コンストラクタで、既存のすべてのジョブを取得してListに追加し、それを返します。
package com.mkyong.scheduler; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.context.FacesContext; import javax.servlet.ServletContext; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.ee.servlet.QuartzInitializerListener; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.matchers.GroupMatcher; @ManagedBean(name = "scheduler") @SessionScoped public class SchedulerBean implements Serializable { private static final long serialVersionUID = 1L; private Scheduler scheduler; private List<QuartzJob> quartzJobList = new ArrayList<QuartzJob>(); public SchedulerBean() throws SchedulerException { ServletContext servletContext = (ServletContext) FacesContext .getCurrentInstance().getExternalContext().getContext(); //Get QuartzInitializerListener StdSchedulerFactory stdSchedulerFactory = (StdSchedulerFactory) servletContext .getAttribute(QuartzInitializerListener.QUARTZ__FACTORY__KEY); scheduler = stdSchedulerFactory.getScheduler(); //loop jobs by group for (String groupName : scheduler.getJobGroupNames()) { //get jobkey for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher .jobGroupEquals(groupName))) { String jobName = jobKey.getName(); String jobGroup = jobKey.getGroup(); //get job's trigger List<Trigger> triggers = (List<Trigger>) scheduler .getTriggersOfJob(jobKey); Date nextFireTime = triggers.get(0).getNextFireTime(); quartzJobList.add(new QuartzJob(jobName, jobGroup, nextFireTime)); } } } //trigger a job public void fireNow(String jobName, String jobGroup) throws SchedulerException { JobKey jobKey = new JobKey(jobName, jobGroup); scheduler.triggerJob(jobKey); } public List<QuartzJob> getQuartzJobList() { return quartzJobList; } public static class QuartzJob { private static final long serialVersionUID = 1L; String jobName; String jobGroup; Date nextFireTime; public QuartzJob(String jobName, String jobGroup, Date nextFireTime) { this.jobName = jobName; this.jobGroup = jobGroup; this.nextFireTime = nextFireTime; } public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } public Date getNextFireTime() { return nextFireTime; } public void setNextFireTime(Date nextFireTime) { this.nextFireTime = nextFireTime; } } }
5. JSFページ
Webページで、EL##scheduler.quartzJobListを介して既存のすべてのジョブを取得し、 `dataTable`コンポーネントを介して表示します。 「fireNow」リンクをクリックすると、指定したジョブがただちに起動されます。
File:welcome.xhtml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> <h:outputStylesheet library="css" name="table-style.css"/> </h:head> <h:body> <h1>All Quartz Jobs</h1> <h:form> <h:dataTable value="#{scheduler.quartzJobList}" var="quartz" styleClass="quartz-table" headerClass="quartz-table-header" rowClasses="quartz-table-odd-row,quartz-table-even-row"> <h:column> <!-- column header --> <f:facet name="header">Job Name</f:facet> <!-- row record --> #{quartz.jobName} </h:column> <h:column> <f:facet name="header">Job Group</f:facet> #{quartz.jobGroup} </h:column> <h:column> <f:facet name="header">Next Fire Time</f:facet> <h:outputText value="#{quartz.nextFireTime}"> <f:convertDateTime pattern="dd.MM.yyyy HH:mm"/> </h:outputText> </h:column> <h:column> <f:facet name="header">Action</f:facet> <h:commandLink value="Fire Now" action="#{scheduler.fireNow(quartz.jobName, quartz.jobGroup)}"/> </h:column> </h:dataTable> </h:form> </h:body> </html>
File:table-style.css
.quartz-table{ border-collapse:collapse; } .quartz-table-header{ text-align:center; background:none repeat scroll 0 0 #E5E5E5; border-bottom:1px solid #BBBBBB; padding:16px; } .quartz-table-odd-row{ text-align:center; background:none repeat scroll 0 0 #FFFFFFF; border-top:1px solid #BBBBBB; padding:20px; } .quartz-table-even-row{ text-align:center; background:none repeat scroll 0 0 #F9F9F9; border-top:1px solid #BBBBBB; padding:20px; }
ソースコードをダウンロードする
それをダウンロードする –
JSF-Quartz-Trigger-Job-Manually.zip
(28 kb)
参考文献
管理者ページの例]。 link://jsf2/jsf-2-quartz-2-example/[Quartz 2 JSF 2の統合
例]。
http://quartz-scheduler.org/api/2.0.0/org/quartz/ee/servlet/QuartzInitializerListener.html
[JQuartzInitializerListener
JavaDoc]。リンク://java/example-to-run-multiple-jobs-in-quartz/[複数のジョブ
石英]